From 12fd0f35c9030d65b1c16c895208e2b97b6befd1 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 6 Sep 2016 16:12:05 +0200 Subject: [PATCH 1/7] convert ErrorReportConfigurable to kotlin --- .../diagnostic/ErrorReportConfigurable.java | 61 ++++++++----------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java index e738a646c5e3..367420a80234 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java @@ -13,45 +13,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.diagnostic; +package com.intellij.diagnostic -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.credentialStore.Credentials; -import com.intellij.ide.passwordSafe.PasswordSafe; -import com.intellij.openapi.components.*; -import com.intellij.openapi.util.text.StringUtil; -import org.jetbrains.annotations.Nullable; +import com.intellij.credentialStore.CredentialAttributes +import com.intellij.credentialStore.Credentials +import com.intellij.ide.passwordSafe.PasswordSafe +import com.intellij.openapi.components.* +import com.intellij.util.decodeBase64 -import java.util.Base64; +@State(name = "ErrorReportConfigurable", storages = arrayOf(Storage(value = "other.xml", deprecated = true, roamingType = RoamingType.DISABLED))) +internal class ErrorReportConfigurable : PersistentStateComponent { + override fun getState() = OldState() -@State(name = "ErrorReportConfigurable", storages = @Storage(value = "other.xml", deprecated = true, roamingType = RoamingType.DISABLED)) -class ErrorReportConfigurable implements PersistentStateComponent { - public static final String SERVICE_NAME = "IntelliJ Platform — JetBrains Account"; - - static class State { - public String ITN_LOGIN; - public String ITN_PASSWORD_CRYPT; - } - - public static ErrorReportConfigurable getInstance() { - return ServiceManager.getService(ErrorReportConfigurable.class); - } - - @Nullable - @Override - public State getState() { - return new State(); - } - - @Override - public void loadState(State state) { - if (!StringUtil.isEmpty(state.ITN_LOGIN) || !StringUtil.isEmpty(state.ITN_PASSWORD_CRYPT)) { - PasswordSafe.getInstance().set(new CredentialAttributes(SERVICE_NAME, state.ITN_LOGIN), new Credentials(state.ITN_LOGIN, Base64.getDecoder().decode(state.ITN_PASSWORD_CRYPT))); + override fun loadState(state: OldState) { + if (!state.ITN_LOGIN.isNullOrEmpty() || !state.ITN_PASSWORD_CRYPT.isNullOrEmpty()) { + PasswordSafe.getInstance().set(CredentialAttributes(SERVICE_NAME, state.ITN_LOGIN), Credentials(state.ITN_LOGIN, state.ITN_PASSWORD_CRYPT!!.decodeBase64())) } } - @Nullable - public static Credentials getCredentials() { - return PasswordSafe.getInstance().get(new CredentialAttributes(SERVICE_NAME)); + companion object { + @JvmStatic + val SERVICE_NAME = "IntelliJ Platform — JetBrains Account" + + val instance: ErrorReportConfigurable + get() = ServiceManager.getService(ErrorReportConfigurable::class.java) + + @JvmStatic + val credentials: Credentials? + get() = PasswordSafe.getInstance().get(CredentialAttributes(SERVICE_NAME)) } } + +internal class OldState { + var ITN_LOGIN: String? = null + var ITN_PASSWORD_CRYPT: String? = null +} \ No newline at end of file From dff0b496567a20418b9869179363cd4497bfeaa6 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 6 Sep 2016 16:12:24 +0200 Subject: [PATCH 2/7] convert ErrorReportConfigurable to kotlin --- .../{ErrorReportConfigurable.java => ErrorReportConfigurable.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/platform-impl/src/com/intellij/diagnostic/{ErrorReportConfigurable.java => ErrorReportConfigurable.kt} (100%) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt similarity index 100% rename from platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java rename to platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt From 1dd25fcc57c7aa4fbafaec2651dc90e3825fdad8 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 6 Sep 2016 16:28:07 +0200 Subject: [PATCH 3/7] convert ITNReporter, JetBrainsAccountDialog to kotlin --- .../com/intellij/diagnostic/ITNReporter.java | 328 ++++++++---------- .../diagnostic/JetBrainsAccountDialog.java | 126 ++++--- 2 files changed, 212 insertions(+), 242 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java index 4fae72516f46..b24a5c39dcda 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java @@ -13,192 +13,170 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.diagnostic; +package com.intellij.diagnostic -import com.intellij.CommonBundle; -import com.intellij.credentialStore.CredentialAttributesKt; -import com.intellij.credentialStore.Credentials; -import com.intellij.errorreport.bean.ErrorBean; -import com.intellij.errorreport.error.InternalEAPException; -import com.intellij.errorreport.error.NoSuchEAPUserException; -import com.intellij.errorreport.error.UpdateAvailableException; -import com.intellij.errorreport.itn.ITNProxy; -import com.intellij.ide.DataManager; -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManager; -import com.intellij.idea.IdeaLogger; -import com.intellij.notification.NotificationListener; -import com.intellij.notification.NotificationType; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.ErrorReportSubmitter; -import com.intellij.openapi.diagnostic.IdeaLoggingEvent; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.diagnostic.SubmittedReportInfo; -import com.intellij.openapi.extensions.PluginId; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Consumer; -import com.intellij.xml.util.XmlStringUtil; -import org.jetbrains.annotations.NotNull; +import com.intellij.CommonBundle +import com.intellij.errorreport.bean.ErrorBean +import com.intellij.errorreport.error.InternalEAPException +import com.intellij.errorreport.error.NoSuchEAPUserException +import com.intellij.errorreport.error.UpdateAvailableException +import com.intellij.errorreport.itn.ITNProxy +import com.intellij.ide.DataManager +import com.intellij.ide.plugins.PluginManager +import com.intellij.idea.IdeaLogger +import com.intellij.notification.NotificationListener +import com.intellij.notification.NotificationType +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.diagnostic.ErrorReportSubmitter +import com.intellij.openapi.diagnostic.IdeaLoggingEvent +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.diagnostic.SubmittedReportInfo +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages +import com.intellij.util.Consumer +import com.intellij.xml.util.XmlStringUtil +import java.awt.Component +import javax.swing.Icon -import javax.swing.*; -import java.awt.*; +private var previousExceptionThreadId = 0 -/** - * @author max - */ -public class ITNReporter extends ErrorReportSubmitter { - private static int previousExceptionThreadId = 0; +open class ITNReporter : ErrorReportSubmitter() { + override fun getReportActionText(): String = DiagnosticBundle.message("error.report.to.jetbrains.action") - @Override - public String getReportActionText() { - return DiagnosticBundle.message("error.report.to.jetbrains.action"); - } - - @Override - public boolean submit(@NotNull IdeaLoggingEvent[] events, - String additionalInfo, - @NotNull Component parentComponent, - @NotNull Consumer consumer) { - ErrorBean errorBean = new ErrorBean(events[0].getThrowable(), IdeaLogger.ourLastActionId); - return doSubmit(events[0], parentComponent, consumer, errorBean, additionalInfo); + override fun submit(events: Array, + additionalInfo: String?, + parentComponent: Component, + consumer: Consumer): Boolean { + return submit(events.get(0), parentComponent, consumer, ErrorBean(events.get(0).throwable, IdeaLogger.ourLastActionId), additionalInfo) } /** * Used to enable error reporting even in release versions. */ - public boolean showErrorInRelease(IdeaLoggingEvent event) { - return false; - } + open fun showErrorInRelease(event: IdeaLoggingEvent) = false +} - private static boolean doSubmit(final IdeaLoggingEvent event, - final Component parentComponent, - final Consumer callback, - final ErrorBean errorBean, - final String description) { - Credentials credentials = ErrorReportConfigurable.getCredentials(); - if (!CredentialAttributesKt.isFulfilled(credentials)) { - if (!new JetBrainsAccountDialog(parentComponent).showAndGet()) { - return false; +fun setPluginInfo(event: IdeaLoggingEvent, errorBean: ErrorBean) { + val t = event.throwable + if (t != null) { + val pluginId = IdeErrorsDialog.findPluginId(t) + if (pluginId != null) { + val ideaPluginDescriptor = PluginManager.getPlugin(pluginId) + if (ideaPluginDescriptor != null && (!ideaPluginDescriptor.isBundled || ideaPluginDescriptor.allowBundledUpdate())) { + errorBean.pluginName = ideaPluginDescriptor.name + errorBean.pluginVersion = ideaPluginDescriptor.version } - - credentials = ErrorReportConfigurable.getCredentials(); - } - - errorBean.setDescription(description); - errorBean.setMessage(event.getMessage()); - - if (previousExceptionThreadId != 0) { - errorBean.setPreviousException(previousExceptionThreadId); - } - - setPluginInfo(event, errorBean); - - Object data = event.getData(); - if (data instanceof AbstractMessage) { - errorBean.setAssigneeId(((AbstractMessage)data).getAssigneeId()); - errorBean.setAttachments(((AbstractMessage)data).getIncludedAttachments()); - } - - String login = credentials == null ? null : credentials.getUserName(); - String password = credentials == null ? null : credentials.getPasswordAsString(); - if (StringUtil.isEmptyOrSpaces(login) && StringUtil.isEmptyOrSpaces(password)) { - login = "idea_anonymous"; - password = "guest"; - } - - Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent)); - ITNProxy.sendError(project, login, password, errorBean, threadId -> { - updatePreviousThreadId(threadId); - String url = ITNProxy.getBrowseUrl(threadId); - String linkText = String.valueOf(threadId); - final SubmittedReportInfo reportInfo = new SubmittedReportInfo(url, linkText, SubmittedReportInfo.SubmissionStatus.NEW_ISSUE); - callback.consume(reportInfo); - ApplicationManager.getApplication().invokeLater(() -> { - StringBuilder text = new StringBuilder(); - IdeErrorsDialog.appendSubmissionInformation(reportInfo, text); - text.append('.').append("
").append(DiagnosticBundle.message("error.report.gratitude")); - String content = XmlStringUtil.wrapInHtml(text); - ReportMessages.GROUP - .createNotification(ReportMessages.ERROR_REPORT, content, NotificationType.INFORMATION, NotificationListener.URL_OPENING_LISTENER) - .setImportant(false) - .notify(project); - }); - }, e -> { - Logger.getInstance(ITNReporter.class).info("reporting failed: " + e); - ApplicationManager.getApplication().invokeLater(() -> { - String msg; - if (e instanceof NoSuchEAPUserException) { - msg = DiagnosticBundle.message("error.report.authentication.failed"); - } - else if (e instanceof InternalEAPException) { - msg = DiagnosticBundle.message("error.report.posting.failed", e.getMessage()); - } - else { - msg = DiagnosticBundle.message("error.report.sending.failure"); - } - if (e instanceof UpdateAvailableException) { - String message = DiagnosticBundle.message("error.report.new.eap.build.message", e.getMessage()); - showMessageDialog(parentComponent, project, message, CommonBundle.getWarningTitle(), Messages.getWarningIcon()); - callback.consume(new SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED)); - } - else if (showYesNoDialog(parentComponent, project, msg, ReportMessages.ERROR_REPORT, Messages.getErrorIcon()) != Messages.YES) { - callback.consume(new SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED)); - } - else { - if (e instanceof NoSuchEAPUserException) { - final JetBrainsAccountDialog dialog; - if (parentComponent.isShowing()) { - dialog = new JetBrainsAccountDialog(parentComponent); - } - else { - dialog = new JetBrainsAccountDialog(project); - } - dialog.show(); - } - ApplicationManager.getApplication().invokeLater(() -> doSubmit(event, parentComponent, callback, errorBean, description)); - } - }); - }); - return true; - } - - public static void setPluginInfo(IdeaLoggingEvent event, ErrorBean errorBean) { - Throwable t = event.getThrowable(); - if (t != null) { - final PluginId pluginId = IdeErrorsDialog.findPluginId(t); - if (pluginId != null) { - final IdeaPluginDescriptor ideaPluginDescriptor = PluginManager.getPlugin(pluginId); - if (ideaPluginDescriptor != null && (!ideaPluginDescriptor.isBundled() || ideaPluginDescriptor.allowBundledUpdate())) { - errorBean.setPluginName(ideaPluginDescriptor.getName()); - errorBean.setPluginVersion(ideaPluginDescriptor.getVersion()); - } - } - } - } - - private static void updatePreviousThreadId(Integer threadId) { - previousExceptionThreadId = threadId; - } - - private static void showMessageDialog(Component parentComponent, Project project, String message, String title, Icon icon) { - if (parentComponent.isShowing()) { - Messages.showMessageDialog(parentComponent, message, title, icon); - } - else { - Messages.showMessageDialog(project, message, title, icon); - } - } - - @Messages.YesNoResult - private static int showYesNoDialog(Component parentComponent, Project project, String message, String title, Icon icon) { - if (parentComponent.isShowing()) { - return Messages.showYesNoDialog(parentComponent, message, title, icon); - } - else { - return Messages.showYesNoDialog(project, message, title, icon); } } } + +private fun updatePreviousThreadId(threadId: Int?) { + previousExceptionThreadId = threadId!! +} + +private fun showMessageDialog(parentComponent: Component, project: Project?, message: String, title: String, icon: Icon) { + if (parentComponent.isShowing) { + Messages.showMessageDialog(parentComponent, message, title, icon) + } + else { + Messages.showMessageDialog(project, message, title, icon) + } +} + +@Messages.YesNoResult +private fun showYesNoDialog(parentComponent: Component, project: Project?, message: String, title: String, icon: Icon): Int { + if (parentComponent.isShowing) { + return Messages.showYesNoDialog(parentComponent, message, title, icon) + } + else { + return Messages.showYesNoDialog(project, message, title, icon) + } +} + +private fun submit(event: IdeaLoggingEvent, parentComponent: Component, callback: Consumer, errorBean: ErrorBean, description: String?): Boolean { + var credentials = ErrorReportConfigurable.getCredentials() + // ask password only if user name was specified + if (credentials?.userName != null && credentials?.password.isNullOrEmpty()) { + if (!JetBrainsAccountDialog(parentComponent).showAndGet()) { + return false + } + + credentials = ErrorReportConfigurable.getCredentials() + } + + errorBean.description = description + errorBean.message = event.message + + if (previousExceptionThreadId != 0) { + errorBean.previousException = previousExceptionThreadId + } + + setPluginInfo(event, errorBean) + + val data = event.data + if (data is AbstractMessage) { + errorBean.assigneeId = data.assigneeId + errorBean.attachments = data.includedAttachments + } + + var login = credentials?.userName + var password = credentials?.getPasswordAsString() + if (login.isNullOrBlank() && password.isNullOrBlank()) { + login = "idea_anonymous" + password = "guest" + } + + val project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent)) + ITNProxy.sendError(project, login, password, errorBean, { threadId -> + updatePreviousThreadId(threadId) + val url = ITNProxy.getBrowseUrl(threadId!!) + val linkText = threadId.toString() + val reportInfo = SubmittedReportInfo(url, linkText, SubmittedReportInfo.SubmissionStatus.NEW_ISSUE) + callback.consume(reportInfo) + ApplicationManager.getApplication().invokeLater { + val text = StringBuilder() + IdeErrorsDialog.appendSubmissionInformation(reportInfo, text) + text.append('.').append("
").append(DiagnosticBundle.message("error.report.gratitude")) + val content = XmlStringUtil.wrapInHtml(text) + ReportMessages.GROUP.createNotification(ReportMessages.ERROR_REPORT, content, NotificationType.INFORMATION, + NotificationListener.URL_OPENING_LISTENER).setImportant(false).notify(project) + } + }) { e -> + Logger.getInstance(ITNReporter::class.java).info("reporting failed: " + e) + ApplicationManager.getApplication().invokeLater { + val msg: String + if (e is NoSuchEAPUserException) { + msg = DiagnosticBundle.message("error.report.authentication.failed") + } + else if (e is InternalEAPException) { + msg = DiagnosticBundle.message("error.report.posting.failed", e.message) + } + else { + msg = DiagnosticBundle.message("error.report.sending.failure") + } + if (e is UpdateAvailableException) { + val message = DiagnosticBundle.message("error.report.new.eap.build.message", e.message) + showMessageDialog(parentComponent, project, message, CommonBundle.getWarningTitle(), Messages.getWarningIcon()) + callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED)) + } + else if (showYesNoDialog(parentComponent, project, msg, ReportMessages.ERROR_REPORT, Messages.getErrorIcon()) != Messages.YES) { + callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED)) + } + else { + if (e is NoSuchEAPUserException) { + val dialog: JetBrainsAccountDialog + if (parentComponent.isShowing) { + dialog = JetBrainsAccountDialog(parentComponent) + } + else { + dialog = JetBrainsAccountDialog(project!!) + } + dialog.show() + } + ApplicationManager.getApplication().invokeLater { submit(event, parentComponent, callback, errorBean, description) } + } + } + } + return true +} diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java index d8d04b8b88bc..b0736eff2453 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java @@ -13,99 +13,91 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.diagnostic; +package com.intellij.diagnostic -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.credentialStore.Credentials; -import com.intellij.ide.BrowserUtil; -import com.intellij.ide.passwordSafe.PasswordSafe; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.ClickListener; -import com.intellij.util.net.HttpConfigurable; -import org.jetbrains.annotations.NotNull; +import com.intellij.credentialStore.CredentialAttributes +import com.intellij.credentialStore.Credentials +import com.intellij.ide.BrowserUtil +import com.intellij.ide.passwordSafe.PasswordSafe +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.DialogWrapper +import com.intellij.openapi.util.text.StringUtil +import com.intellij.ui.ClickListener +import com.intellij.util.net.HttpConfigurable -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseEvent; +import javax.swing.* +import java.awt.* +import java.awt.event.MouseEvent -public class JetBrainsAccountDialog extends DialogWrapper { - private JTextField myItnLoginTextField; - private JPasswordField myPasswordText; - private JCheckBox myRememberCheckBox; +class JetBrainsAccountDialog : DialogWrapper { + private val myItnLoginTextField: JTextField? = null + private val myPasswordText: JPasswordField? = null + private val myRememberCheckBox: JCheckBox? = null - public JetBrainsAccountDialog(Component parent) throws HeadlessException { - super(parent, false); - init(); + @Throws(HeadlessException::class) + constructor(parent: Component) : super(parent, false) { + init() } - public JetBrainsAccountDialog(Project project) throws HeadlessException { - super(project, false); - init(); + @Throws(HeadlessException::class) + constructor(project: Project) : super(project, false) { + init() } - protected JPanel myMainPanel; - protected JLabel mySendingSettingsLabel; - private JLabel myCreateAccountLabel; + var myMainPanel: JPanel? = null + var mySendingSettingsLabel: JLabel? = null + private val myCreateAccountLabel: JLabel? = null - @Override - protected String getDimensionServiceKey() { - return "#com.intellij.diagnostic.AbstractSendErrorDialog"; + override fun getDimensionServiceKey(): String? { + return "#com.intellij.diagnostic.AbstractSendErrorDialog" } - @Override - public JComponent getPreferredFocusedComponent() { - return myItnLoginTextField; + override fun getPreferredFocusedComponent(): JComponent? { + return myItnLoginTextField } - @Override - protected void init() { - setTitle(ReportMessages.ERROR_REPORT); - getContentPane().add(myMainPanel); + override fun init() { + title = ReportMessages.ERROR_REPORT + contentPane.add(myMainPanel) - new ClickListener() { - @Override - public boolean onClick(@NotNull MouseEvent e, int clickCount) { - HttpConfigurable.editConfigurable(myMainPanel); - return true; + object : ClickListener() { + override fun onClick(e: MouseEvent, clickCount: Int): Boolean { + HttpConfigurable.editConfigurable(myMainPanel) + return true } - }.installOn(mySendingSettingsLabel); + }.installOn(mySendingSettingsLabel!!) - mySendingSettingsLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + mySendingSettingsLabel!!.cursor = Cursor(Cursor.HAND_CURSOR) - Credentials credentials = ErrorReportConfigurable.getCredentials(); - String userName = credentials == null ? null : credentials.getUserName(); - myItnLoginTextField.setText(userName); - String password = credentials == null ? null : credentials.getPasswordAsString(); - myPasswordText.setText(password); + val credentials = ErrorReportConfigurable.getCredentials() + val userName = credentials?.userName + myItnLoginTextField!!.text = userName + val password = credentials?.getPasswordAsString() + myPasswordText!!.text = password // if no user name - never stored and so, defaults to remember. if user name set, but no password, so, previously was stored without password - myRememberCheckBox.setSelected(StringUtil.isEmpty(userName) || !StringUtil.isEmpty(password)); + myRememberCheckBox!!.isSelected = StringUtil.isEmpty(userName) || !StringUtil.isEmpty(password) - new ClickListener() { - @Override - public boolean onClick(@NotNull MouseEvent e, int clickCount) { - BrowserUtil.browse("http://account.jetbrains.com"); - return true; + object : ClickListener() { + override fun onClick(e: MouseEvent, clickCount: Int): Boolean { + BrowserUtil.browse("http://account.jetbrains.com") + return true } - }.installOn(myCreateAccountLabel); - myCreateAccountLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + }.installOn(myCreateAccountLabel!!) + myCreateAccountLabel.cursor = Cursor(Cursor.HAND_CURSOR) - super.init(); + super.init() } - @Override - protected void doOKAction() { - String userName = myItnLoginTextField.getText(); + override fun doOKAction() { + val userName = myItnLoginTextField!!.text if (!StringUtil.isEmpty(userName)) { - PasswordSafe.getInstance().set(new CredentialAttributes(ErrorReportConfigurable.SERVICE_NAME, userName), - new Credentials(userName, myRememberCheckBox.isSelected() ? myPasswordText.getPassword() : null)); + PasswordSafe.getInstance().set(CredentialAttributes(ErrorReportConfigurable.SERVICE_NAME, userName), + Credentials(userName, if (myRememberCheckBox!!.isSelected) myPasswordText!!.password else null)) } - super.doOKAction(); + super.doOKAction() } - @Override - protected JComponent createCenterPanel() { - return myMainPanel; + override fun createCenterPanel(): JComponent? { + return myMainPanel } } From 8d1211a2f885bf52ea79bdc8c2c0f258d924de43 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 6 Sep 2016 16:28:26 +0200 Subject: [PATCH 4/7] convert ITNReporter, JetBrainsAccountDialog to kotlin --- .../{ITNReporter.java => ITNReporter.kt} | 20 +++++++++---------- ...tDialog.java => JetBrainsAccountDialog.kt} | 0 2 files changed, 9 insertions(+), 11 deletions(-) rename platform/platform-impl/src/com/intellij/diagnostic/{ITNReporter.java => ITNReporter.kt} (93%) rename platform/platform-impl/src/com/intellij/diagnostic/{JetBrainsAccountDialog.java => JetBrainsAccountDialog.kt} (100%) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt similarity index 93% rename from platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java rename to platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt index b24a5c39dcda..f92a81299bdb 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt @@ -163,19 +163,17 @@ private fun submit(event: IdeaLoggingEvent, parentComponent: Component, callback else if (showYesNoDialog(parentComponent, project, msg, ReportMessages.ERROR_REPORT, Messages.getErrorIcon()) != Messages.YES) { callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED)) } - else { - if (e is NoSuchEAPUserException) { - val dialog: JetBrainsAccountDialog - if (parentComponent.isShowing) { - dialog = JetBrainsAccountDialog(parentComponent) - } - else { - dialog = JetBrainsAccountDialog(project!!) - } - dialog.show() + else if (e is NoSuchEAPUserException) { + val dialog: JetBrainsAccountDialog + if (parentComponent.isShowing) { + dialog = JetBrainsAccountDialog(parentComponent) } - ApplicationManager.getApplication().invokeLater { submit(event, parentComponent, callback, errorBean, description) } + else { + dialog = JetBrainsAccountDialog(project!!) + } + dialog.show() } + ApplicationManager.getApplication().invokeLater { submit(event, parentComponent, callback, errorBean, description) } } } return true diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.kt similarity index 100% rename from platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java rename to platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.kt From aebe2fdfc5345054f261d7f7286368f7fd2a170d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 7 Sep 2016 07:49:49 +0200 Subject: [PATCH 5/7] =?UTF-8?q?LinkLabel=20=E2=80=94=20simplify=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EnterPasswordComponent.java | 3 +- .../diagnostic/ErrorReportSubmitter.java | 3 +- .../com/intellij/openapi/ui/dialogBuilder.kt | 12 +++- .../ui/components/labels/LinkLabel.java | 25 +++++-- .../ui/components/labels/SwingActionLink.java | 10 ++- .../src/com/intellij/util/string.kt | 5 +- .../diagnostic/ErrorReportConfigurable.kt | 5 +- .../com/intellij/diagnostic/ITNReporter.kt | 25 ++----- .../intellij/diagnostic/IdeErrorsDialog.java | 4 +- .../diagnostic/JetBrainsAccountDialog.kt | 40 +++++++----- .../diagnostic/JetBrainsAccountForm.form | 2 +- .../options/newEditor/ConfigurableEditor.java | 11 +--- .../src/com/intellij/ui/components.kt | 65 +++++++++++++++++++ .../src/com/intellij/ui/layout/layout.kt | 58 +++-------------- .../src/messages/DiagnosticBundle.properties | 1 - .../VcsUpdateInfoScopeFilterConfigurable.java | 14 ++-- .../xdebugger/impl/ui/BreakpointEditor.java | 19 ++---- .../src/git4idea/crlf/GitCrlfDialog.java | 10 +-- plugins/settings-repository/src/authForm.kt | 1 + 19 files changed, 167 insertions(+), 146 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ui/components.kt diff --git a/platform/credential-store/src/com/intellij/credentialStore/EnterPasswordComponent.java b/platform/credential-store/src/com/intellij/credentialStore/EnterPasswordComponent.java index 785707d0e2f7..5fb91e63e7ac 100644 --- a/platform/credential-store/src/com/intellij/credentialStore/EnterPasswordComponent.java +++ b/platform/credential-store/src/com/intellij/credentialStore/EnterPasswordComponent.java @@ -20,6 +20,7 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.SystemInfo; +import com.intellij.ui.ComponentsKt; import com.intellij.ui.layout.LayoutKt; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -96,6 +97,6 @@ class EnterPasswordComponent { note = "The passwords will be stored in IDE configuration files with weak protection
(" + subNote + ")."; } - myPromptLabel = LayoutKt.htmlComponent("Master password is required to convert saved passwords.
" + note, UIUtil.getLabelFont(UIUtil.FontSize.SMALL)); + myPromptLabel = ComponentsKt.htmlComponent("Master password is required to convert saved passwords.
" + note, UIUtil.getLabelFont(UIUtil.FontSize.SMALL)); } } diff --git a/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java b/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java index c68e45189a95..c9c4fbca6a21 100644 --- a/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java +++ b/platform/platform-api/src/com/intellij/openapi/diagnostic/ErrorReportSubmitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +48,7 @@ public abstract class ErrorReportSubmitter implements PluginAware { /** * @return an action text to be used in Error Reporter user interface, e.g. "Report to JetBrains". */ + @NotNull public abstract String getReportActionText(); /** diff --git a/platform/platform-api/src/com/intellij/openapi/ui/dialogBuilder.kt b/platform/platform-api/src/com/intellij/openapi/ui/dialogBuilder.kt index 04f44c205ac6..3c771baaeb96 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/dialogBuilder.kt +++ b/platform/platform-api/src/com/intellij/openapi/ui/dialogBuilder.kt @@ -15,10 +15,18 @@ */ package com.intellij.openapi.ui +import com.intellij.openapi.project.Project +import java.awt.Component import javax.swing.JComponent -fun dialog(title: String, centerPanel: JComponent, resizable: Boolean = true, preferedFocusComponent: JComponent? = null, okActionEnabled: Boolean = true): DialogBuilder { - val builder = DialogBuilder() +fun dialog(title: String, + centerPanel: JComponent, + resizable: Boolean = true, + preferedFocusComponent: JComponent? = null, + okActionEnabled: Boolean = true, + project: Project? = null, + parent: Component? = null): DialogBuilder { + val builder = if (parent == null) DialogBuilder(project) else DialogBuilder(parent) builder .title(title) .centerPanel(centerPanel) diff --git a/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java b/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java index a6960b82d303..8e85f6de64e9 100644 --- a/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java +++ b/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import com.intellij.ui.UI; import com.intellij.util.ui.JBRectangle; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.accessibility.ScreenReader; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,7 +35,6 @@ import javax.accessibility.AccessibleRole; import javax.swing.*; import java.awt.*; import java.awt.event.*; -import java.util.HashSet; import java.util.Set; /** @@ -46,7 +46,7 @@ public class LinkLabel extends JLabel { private LinkListener myLinkListener; private T myLinkData; - private static final Set ourVisitedLinks = new HashSet<>(); + private static final Set ourVisitedLinks = new THashSet<>(); private boolean myIsLinkActive; @@ -69,6 +69,16 @@ public class LinkLabel extends JLabel { this(text, icon, aListener, null, null); } + @NotNull + public static LinkLabel create(@Nullable String text, @Nullable Runnable action) { + return new LinkLabel<>(text, null, action == null ? null : new LinkListener() { + @Override + public void linkSelected(LinkLabel source, Object linkData) { + action.run(); + } + }, null, null); + } + public LinkLabel(String text, @Nullable Icon icon, @Nullable LinkListener aListener, @Nullable T aLinkData) { this(text, icon, aListener, aLinkData, null); } @@ -142,8 +152,12 @@ public class LinkLabel extends JLabel { try { myClickIsBeingProcessed = true; - if (myLinkListener != null) myLinkListener.linkSelected(this, myLinkData); - ourVisitedLinks.add(myVisitedLinksKey); + if (myLinkListener != null) { + myLinkListener.linkSelected(this, myLinkData); + } + if (myVisitedLinksKey != null) { + ourVisitedLinks.add(myVisitedLinksKey); + } repaint(); } finally { @@ -222,7 +236,6 @@ public class LinkLabel extends JLabel { } protected void onSetActive(boolean active) { - } private final JBRectangle iconR = new JBRectangle(); diff --git a/platform/platform-api/src/com/intellij/ui/components/labels/SwingActionLink.java b/platform/platform-api/src/com/intellij/ui/components/labels/SwingActionLink.java index 993cb3d8da7b..90c67984d184 100644 --- a/platform/platform-api/src/com/intellij/ui/components/labels/SwingActionLink.java +++ b/platform/platform-api/src/com/intellij/ui/components/labels/SwingActionLink.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,11 @@ package com.intellij.ui.components.labels; import org.jetbrains.annotations.NotNull; -import javax.swing.Action; -import javax.swing.Icon; +import javax.swing.*; import java.awt.event.ActionEvent; +import java.beans.EventHandler; import java.beans.PropertyChangeListener; -import static java.beans.EventHandler.create; - /** * @author Sergey.Malenkov */ @@ -35,7 +33,7 @@ public class SwingActionLink extends LinkLabel implements LinkListener { get() = ServiceManager.getService(ErrorReportConfigurable::class.java) @JvmStatic - val credentials: Credentials? - get() = PasswordSafe.getInstance().get(CredentialAttributes(SERVICE_NAME)) + fun getCredentials() = PasswordSafe.getInstance().get(CredentialAttributes(SERVICE_NAME)) } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt index f92a81299bdb..efd64ed10afc 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/ITNReporter.kt @@ -98,7 +98,7 @@ private fun submit(event: IdeaLoggingEvent, parentComponent: Component, callback var credentials = ErrorReportConfigurable.getCredentials() // ask password only if user name was specified if (credentials?.userName != null && credentials?.password.isNullOrEmpty()) { - if (!JetBrainsAccountDialog(parentComponent).showAndGet()) { + if (!showJetBrainsAccountDialog(parentComponent).showAndGet()) { return false } @@ -145,16 +145,12 @@ private fun submit(event: IdeaLoggingEvent, parentComponent: Component, callback }) { e -> Logger.getInstance(ITNReporter::class.java).info("reporting failed: " + e) ApplicationManager.getApplication().invokeLater { - val msg: String - if (e is NoSuchEAPUserException) { - msg = DiagnosticBundle.message("error.report.authentication.failed") - } - else if (e is InternalEAPException) { - msg = DiagnosticBundle.message("error.report.posting.failed", e.message) - } - else { - msg = DiagnosticBundle.message("error.report.sending.failure") + val msg = when (e) { + is NoSuchEAPUserException -> DiagnosticBundle.message("error.report.authentication.failed") + is InternalEAPException -> DiagnosticBundle.message("error.report.posting.failed", e.message) + else -> DiagnosticBundle.message("error.report.sending.failure") } + if (e is UpdateAvailableException) { val message = DiagnosticBundle.message("error.report.new.eap.build.message", e.message) showMessageDialog(parentComponent, project, message, CommonBundle.getWarningTitle(), Messages.getWarningIcon()) @@ -164,14 +160,7 @@ private fun submit(event: IdeaLoggingEvent, parentComponent: Component, callback callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED)) } else if (e is NoSuchEAPUserException) { - val dialog: JetBrainsAccountDialog - if (parentComponent.isShowing) { - dialog = JetBrainsAccountDialog(parentComponent) - } - else { - dialog = JetBrainsAccountDialog(project!!) - } - dialog.show() + showJetBrainsAccountDialog(parentComponent, project).show() } ApplicationManager.getApplication().invokeLater { submit(event, parentComponent, callback, errorBean, description) } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 739db6876806..e1c4f4394eeb 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -347,7 +347,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene @Override public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { - new JetBrainsAccountDialog(getRootPane()).show(); + JetBrainsAccountDialogKt.showJetBrainsAccountDialog(getRootPane(), null).show(); updateCredentialsPane(getSelectedMessage()); } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.kt b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.kt index b0736eff2453..656feb7f187a 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.kt +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,31 +19,40 @@ import com.intellij.credentialStore.CredentialAttributes import com.intellij.credentialStore.Credentials import com.intellij.ide.BrowserUtil import com.intellij.ide.passwordSafe.PasswordSafe +import com.intellij.layout.* +import com.intellij.layout.LCFlags.* import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.DialogBuilder import com.intellij.openapi.ui.DialogWrapper +import com.intellij.openapi.ui.dialog import com.intellij.openapi.util.text.StringUtil import com.intellij.ui.ClickListener import com.intellij.util.net.HttpConfigurable - -import javax.swing.* -import java.awt.* +import java.awt.Component +import java.awt.Cursor import java.awt.event.MouseEvent +import javax.swing.* -class JetBrainsAccountDialog : DialogWrapper { +fun showJetBrainsAccountDialog(parent: Component, project: Project? = null): DialogBuilder { + val panel = panel(fillX) { + label(DiagnosticBundle.message("diagnostic.error.report.description")) + link(DiagnosticBundle.message("diagnostic.error.report.proxy.setup")) { + HttpConfigurable.editConfigurable(this) + } + } + + return dialog( + title = DiagnosticBundle.message("error.report.title"), + centerPanel = panel, + project = project, + parent = if (parent.isShowing) parent else null) +} + +class JetBrainsAccountDialog : DialogWrapper(null) { private val myItnLoginTextField: JTextField? = null private val myPasswordText: JPasswordField? = null private val myRememberCheckBox: JCheckBox? = null - @Throws(HeadlessException::class) - constructor(parent: Component) : super(parent, false) { - init() - } - - @Throws(HeadlessException::class) - constructor(project: Project) : super(project, false) { - init() - } - var myMainPanel: JPanel? = null var mySendingSettingsLabel: JLabel? = null private val myCreateAccountLabel: JLabel? = null @@ -57,7 +66,6 @@ class JetBrainsAccountDialog : DialogWrapper { } override fun init() { - title = ReportMessages.ERROR_REPORT contentPane.add(myMainPanel) object : ClickListener() { diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form index e6fc473ec7d1..8a9f985fc7ba 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountForm.form @@ -79,7 +79,7 @@ - + diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java index cb09c138c633..cd3991d65b4a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -291,13 +291,8 @@ class ConfigurableEditor extends AbstractEditor implements AnActionListener, AWT panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); content.add(BorderLayout.CENTER, panel); panel.add(Box.createVerticalStrut(10)); - for (final Configurable current : composite.getConfigurables()) { - LinkLabel label = new LinkLabel(current.getDisplayName(), null) { - @Override - public void doClick() { - openLink(current); - } - }; + for (Configurable current : composite.getConfigurables()) { + LinkLabel label = LinkLabel.create(current.getDisplayName(), () -> openLink(current)); label.setBorder(BorderFactory.createEmptyBorder(1, 17, 3, 1)); panel.add(label); } diff --git a/platform/platform-impl/src/com/intellij/ui/components.kt b/platform/platform-impl/src/com/intellij/ui/components.kt new file mode 100644 index 000000000000..e8c22b59a29c --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/components.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui + +import com.intellij.openapi.vcs.changes.issueLinks.LinkMouseListenerBase +import com.intellij.util.ui.SwingHelper +import com.intellij.util.ui.UIUtil +import java.awt.Color +import java.awt.Font +import java.util.regex.Pattern +import javax.swing.JEditorPane + +private val HREF_PATTERN = Pattern.compile("([^<]*)") +private val LINK_TEXT_ATTRIBUTES = SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, JBColor.blue) +private val SMALL_TEXT_ATTRIBUTES = SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, null) + +fun noteComponent(note: String): SimpleColoredComponent { + val noteComponent = SimpleColoredComponent() + + val matcher = HREF_PATTERN.matcher(note) + var prev = 0 + if (matcher.find()) { + do { + if (matcher.start() != prev) { + noteComponent.append(note.substring(prev, matcher.start()), SMALL_TEXT_ATTRIBUTES) + } + noteComponent.append(matcher.group(2), LINK_TEXT_ATTRIBUTES, SimpleColoredComponent.BrowserLauncherTag(matcher.group(1))) + prev = matcher.end() + } + while (matcher.find()) + + LinkMouseListenerBase.installSingleTagOn(noteComponent) + } + + if (prev < note.length) { + noteComponent.append(note.substring(prev), SMALL_TEXT_ATTRIBUTES) + } + + return noteComponent +} + +@JvmOverloads +fun htmlComponent(text: String = "", font: Font = UIUtil.getLabelFont(), background: Color? = null, foreground: Color? = null, lineWrap: Boolean = false): JEditorPane { + val pane = SwingHelper.createHtmlViewer(lineWrap, font, background, foreground) + if (!text.isNullOrEmpty()) { + pane.text = "${UIUtil.getCssFontDeclaration(font, UIUtil.getLabelForeground(), null, null)}$text" + } + pane.border = null + pane.disabledTextColor = UIUtil.getLabelDisabledForeground() + pane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE) + return pane +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/layout/layout.kt b/platform/platform-impl/src/com/intellij/ui/layout/layout.kt index 20b6482c7935..bfa3e75d2599 100644 --- a/platform/platform-impl/src/com/intellij/ui/layout/layout.kt +++ b/platform/platform-impl/src/com/intellij/ui/layout/layout.kt @@ -16,18 +16,17 @@ package com.intellij.ui.layout import com.intellij.BundleBase -import com.intellij.openapi.vcs.changes.issueLinks.LinkMouseListenerBase -import com.intellij.ui.* +import com.intellij.ui.IdeBorderFactory import com.intellij.ui.components.JBLabel -import com.intellij.util.ui.SwingHelper +import com.intellij.ui.components.labels.LinkLabel import com.intellij.util.ui.UIUtil -import com.intellij.util.ui.UIUtil.getCssFontDeclaration -import com.intellij.util.ui.UIUtil.getLabelForeground import net.miginfocom.layout.* import net.miginfocom.swing.MigLayout -import java.awt.* +import java.awt.BorderLayout +import java.awt.Component +import java.awt.Font +import java.awt.LayoutManager import java.awt.event.ActionEvent -import java.util.regex.Pattern import javax.swing.* // http://www.migcalendar.com/miglayout/mavensite/docs/cheatsheet.pdf @@ -121,6 +120,10 @@ fun JPanel.label(text: String, vararg constraints: CCFlags, componentStyle: UIUt add(label, _cc) } +fun JPanel.link(text: String, action: () -> Unit) { + add(LinkLabel.create(text, action)) +} + private fun gapToBoundSize(value: Int, isHorizontal: Boolean): BoundSize { val unitValue = UnitValue(value.toFloat(), "", isHorizontal, UnitValue.STATIC, null) return BoundSize(unitValue, unitValue, null, false, null) @@ -215,45 +218,4 @@ fun CC.apply(flags: Array): CC { } } return this -} - -private val HREF_PATTERN = Pattern.compile("([^<]*)") -private val LINK_TEXT_ATTRIBUTES = SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, JBColor.blue) -private val SMALL_TEXT_ATTRIBUTES = SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, null) - -fun noteComponent(note: String): SimpleColoredComponent { - val noteComponent = SimpleColoredComponent() - - val matcher = HREF_PATTERN.matcher(note) - var prev = 0 - if (matcher.find()) { - do { - if (matcher.start() != prev) { - noteComponent.append(note.substring(prev, matcher.start()), SMALL_TEXT_ATTRIBUTES) - } - noteComponent.append(matcher.group(2), LINK_TEXT_ATTRIBUTES, SimpleColoredComponent.BrowserLauncherTag(matcher.group(1))) - prev = matcher.end() - } - while (matcher.find()) - - LinkMouseListenerBase.installSingleTagOn(noteComponent) - } - - if (prev < note.length) { - noteComponent.append(note.substring(prev), SMALL_TEXT_ATTRIBUTES) - } - - return noteComponent -} - -@JvmOverloads -fun htmlComponent(text: String = "", font: Font = UIUtil.getLabelFont(), background: Color? = null, foreground: Color? = null, lineWrap: Boolean = false): JEditorPane { - val pane = SwingHelper.createHtmlViewer(lineWrap, font, background, foreground) - if (!text.isNullOrEmpty()) { - pane.text = "${getCssFontDeclaration(font, getLabelForeground(), null, null)}$text" - } - pane.border = null - pane.disabledTextColor = UIUtil.getLabelDisabledForeground() - pane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE) - return pane } \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties index 7d96421f0b62..6989fc38ec71 100644 --- a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties +++ b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties @@ -11,7 +11,6 @@ diagnostic.out.of.memory.dump=Memory Dump diagnostic.error.report.send=&Send diagnostic.error.report.description=If you would like to get notified when the exceptions you submit are fixed,
please fill in your JetBrains Account login and password. diagnostic.error.report.proxy.setup=Set up HTTP proxy settings -diagnostic.error.report.login.group=JetBrains Account diagnostic.error.report.login.remember.password.checkbox=&Remember password diagnostic.error.report.login.name=&Username: diagnostic.error.report.login.password=&Password: diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java index 5c389cab22ed..244e66f2b006 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsUpdateInfoScopeFilterConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.psi.search.scope.packageSet.NamedScope; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; import com.intellij.ui.components.labels.LinkLabel; -import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -91,13 +90,10 @@ class VcsUpdateInfoScopeFilterConfigurable implements Configurable, NamedScopesH panel.add(myCheckbox); panel.add(myComboBox); panel.add(Box.createHorizontalStrut(UIUtil.DEFAULT_HGAP)); - panel.add(new LinkLabel("Manage Scopes", null, new LinkListener() { - @Override - public void linkSelected(LinkLabel aSource, Object aLinkData) { - Settings settings = Settings.KEY.getData(DataManager.getInstance().getDataContext(panel)); - if (settings != null) { - settings.select(settings.find(ScopeChooserConfigurable.PROJECT_SCOPES)); - } + panel.add(LinkLabel.create("Manage Scopes", () -> { + Settings settings = Settings.KEY.getData(DataManager.getInstance().getDataContext(panel)); + if (settings != null) { + settings.select(settings.find(ScopeChooserConfigurable.PROJECT_SCOPES)); } })); return panel; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java index 7167e97f0ede..f6847631809c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/BreakpointEditor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.components.labels.LinkLabel; -import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.impl.actions.XDebuggerActions; @@ -33,13 +32,6 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -/** - * Created with IntelliJ IDEA. - * User: zajac - * Date: 4/4/12 - * Time: 5:51 PM - * To change this template use File | Settings | File Templates. - */ public class BreakpointEditor { public JPanel getMainPanel() { return myMainPanel; @@ -49,12 +41,9 @@ public class BreakpointEditor { AnAction action = ActionManager.getInstance().getAction(XDebuggerActions.VIEW_BREAKPOINTS); String shortcutText = action != null ? KeymapUtil.getFirstKeyboardShortcutText(action) : null; String text = shortcutText != null ? "More (" + shortcutText + ")" : "More"; - myShowMoreOptionsLink = new LinkLabel(text, null, new LinkListener() { - @Override - public void linkSelected(LinkLabel aSource, Object aLinkData) { - if (myDelegate != null) { - myDelegate.more(); - } + myShowMoreOptionsLink = LinkLabel.create(text, () -> { + if (myDelegate != null) { + myDelegate.more(); } }); } diff --git a/plugins/git4idea/src/git4idea/crlf/GitCrlfDialog.java b/plugins/git4idea/src/git4idea/crlf/GitCrlfDialog.java index 35e5a48d8840..89e7121c7416 100644 --- a/plugins/git4idea/src/git4idea/crlf/GitCrlfDialog.java +++ b/plugins/git4idea/src/git4idea/crlf/GitCrlfDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.labels.LinkLabel; -import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -76,12 +75,7 @@ public class GitCrlfDialog extends DialogWrapper { "Fix and Commit: git config --global core.autocrlf " + RECOMMENDED_VALUE + " will be called,
" + "Commit as Is: the config value won't be set.", UIUtil.ComponentStyle.SMALL); - JLabel readMore = new LinkLabel("Read more", null, new LinkListener() { - @Override - public void linkSelected(LinkLabel aSource, Object aLinkData) { - BrowserUtil.browse("https://help.github.com/articles/dealing-with-line-endings"); - } - }); + JLabel readMore = LinkLabel.create("Read more", () -> BrowserUtil.browse("https://help.github.com/articles/dealing-with-line-endings")); JLabel icon = new JLabel(UIUtil.getWarningIcon(), SwingConstants.LEFT); myDontWarn = new JBCheckBox("Don't warn again"); diff --git a/plugins/settings-repository/src/authForm.kt b/plugins/settings-repository/src/authForm.kt index e9378b61a5fe..66031432d686 100644 --- a/plugins/settings-repository/src/authForm.kt +++ b/plugins/settings-repository/src/authForm.kt @@ -24,6 +24,7 @@ import com.intellij.ui.DocumentAdapter import com.intellij.ui.layout.* import com.intellij.ui.layout.CCFlags.* import com.intellij.ui.layout.LCFlags.* +import com.intellij.ui.noteComponent import com.intellij.util.PathUtilRt import com.intellij.util.nullize import com.intellij.util.trimMiddle From 6df5ba3fcbc811cdba17709933f677edf3823311 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 7 Sep 2016 08:06:57 +0200 Subject: [PATCH 6/7] fix after merge --- .idea/codeStyleSettings.xml | 9 +++++++++ .../com/intellij/diagnostic/JetBrainsAccountDialog.kt | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml index e08227b860ba..3ff222636c51 100644 --- a/.idea/codeStyleSettings.xml +++ b/.idea/codeStyleSettings.xml @@ -32,6 +32,15 @@