diff --git a/platform/platform-impl/src/com/intellij/diagnostic/DropAnErrorWithAttachmentsAction.java b/platform/platform-impl/src/com/intellij/diagnostic/DropAnErrorWithAttachmentsAction.java new file mode 100644 index 000000000000..f8b18e7df375 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/diagnostic/DropAnErrorWithAttachmentsAction.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2011 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.diagnostic; + +import com.intellij.diagnostic.errordialog.Attachment; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; + +import java.awt.event.InputEvent; + +@SuppressWarnings({"HardCodedStringLiteral"}) +public class DropAnErrorWithAttachmentsAction extends AnAction { + public DropAnErrorWithAttachmentsAction() { + super("Drop an error with attachments", "Hold down SHIFT for multiple attachments", null); + } + + public void actionPerformed(AnActionEvent e) { + final boolean multipleAttachments = (e.getModifiers() & InputEvent.SHIFT_MASK) != 0; + Attachment[] attachments; + if (multipleAttachments) { + attachments = new Attachment[]{new Attachment("first.txt", "first content"), new Attachment("second.txt", "second content")}; + } + else { + attachments = new Attachment[]{new Attachment("attachment.txt", "content")}; + } + Logger.getInstance("test (with attachments)").error(LogMessageEx.createEvent("test", "test details", attachments)); + } +} diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java index 88a50c44c538..5fd3dd4e8420 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java @@ -38,6 +38,7 @@ import com.intellij.ui.HyperlinkLabel; import com.intellij.ui.IdeBorderFactory; import com.intellij.util.Consumer; import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -58,7 +59,7 @@ import java.util.List; public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListener, TypeSafeDataProvider { private static final Logger LOG = Logger.getInstance(IdeErrorsDialog.class.getName()); - public static final boolean INTERNAL_MODE = ApplicationManagerEx.getApplicationEx().isInternal(); + public static final boolean INTERNAL_MODE = false; //ApplicationManagerEx.getApplicationEx().isInternal(); @NonNls private static final String ACTIVE_TAB_OPTION = IdeErrorsDialog.class.getName() + "activeTab"; public static DataKey CURRENT_TRACE_KEY = DataKey.create("current_stack_trace_key"); public static final int COMPONENTS_WIDTH = 670; @@ -74,6 +75,8 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene private JPanel myCredentialsPanel; private HyperlinkLabel myCredentialsLabel; private JPanel myForeignPluginWarningPanel; + private JPanel myAttachmentWarningPanel; + private HyperlinkLabel myAttachmentWarningLabel; private int myIndex = 0; private final List> myMergedMessages = new ArrayList>(); @@ -246,6 +249,11 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene myTabs.addTab(DiagnosticBundle.message("error.details.tab.title"), myDetailsTabForm.getContentPane()); myAttachmentsTabForm = new AttachmentsTabForm(); + myAttachmentsTabForm.addInclusionListener(new ChangeListener() { + public void stateChanged(final ChangeEvent e) { + updateAttachmentWarning(getSelectedMessage()); + } + }); int activeTabIndex = Integer.parseInt(PropertiesComponent.getInstance().getValue(ACTIVE_TAB_OPTION, "0")); if (activeTabIndex >= myTabs.getTabCount() || activeTabIndex < 0) { @@ -286,6 +294,16 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } }); + myAttachmentWarningLabel.setIcon(UIUtil.getBalloonWarningIcon()); + myAttachmentWarningLabel.addHyperlinkListener(new HyperlinkListener() { + public void hyperlinkUpdate(final HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + myTabs.setSelectedIndex(myTabs.indexOfComponent(myAttachmentsTabForm.getContentPane())); + myAttachmentsTabForm.selectFirstIncludedAttachment(); + } + } + }); + return myContentPane; } @@ -359,6 +377,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene final AbstractMessage message = getSelectedMessage(); updateInfoLabel(message); updateCredentialsPane(message); + updateAttachmentWarning(message); myDisableLink.setVisible(canDisablePlugin(message)); updateForeignPluginLabel(message != null ? message : null); updateTabs(); @@ -370,6 +389,29 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene } } + private void updateAttachmentWarning(final AbstractMessage message) { + final List includedAttachments; + if (message instanceof LogMessageEx && + !(includedAttachments = ContainerUtil.filter(((LogMessageEx)message).getAttachments(), new Condition() { + public boolean value(final Attachment attachment) { + return attachment.isIncluded(); + } + })).isEmpty()) { + myAttachmentWarningPanel.setVisible(true); + if (includedAttachments.size() == 1) { + myAttachmentWarningLabel.setHtmlText( + DiagnosticBundle.message("diagnostic.error.report.include.attachment.warning", includedAttachments.get(0).getName())); + } + else { + myAttachmentWarningLabel.setHtmlText( + DiagnosticBundle.message("diagnostic.error.report.include.attachments.warning", includedAttachments.size())); + } + } + else { + myAttachmentWarningPanel.setVisible(false); + } + } + private static boolean canDisablePlugin(AbstractMessage message) { if (message == null) { return false; diff --git a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java index 26f602a1ec72..312f8ea67c93 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/AttachmentsTabForm.java @@ -4,10 +4,13 @@ import com.intellij.diagnostic.DiagnosticBundle; import com.intellij.ide.plugins.InstalledPluginsTableModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.table.TableView; +import com.intellij.util.EventDispatcher; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.event.ActionEvent; @@ -23,6 +26,7 @@ public class AttachmentsTabForm { private JPanel myContentPane; private TableView myTable; private LabeledTextComponent myFileTextArea; + private final EventDispatcher myInclusionEventDispatcher = EventDispatcher.create(ChangeListener.class); private final ColumnInfo ENABLED_COLUMN = new ColumnInfo(DiagnosticBundle.message("error.dialog.attachment.include.column.title")) { @@ -49,6 +53,7 @@ public class AttachmentsTabForm { @Override public void setValue(Attachment attachment, Boolean value) { attachment.setIncluded(value); + myInclusionEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(attachment)); } }; @@ -110,4 +115,18 @@ public class AttachmentsTabForm { public JPanel getContentPane() { return myContentPane; } + + public void addInclusionListener(ChangeListener listener) { + myInclusionEventDispatcher.addListener(listener); + } + + public void selectFirstIncludedAttachment() { + final List items = ((ListTableModel)myTable.getModel()).getItems(); + for (Object item : items) { + if (((Attachment)item).isIncluded()) { + myTable.setSelection(Collections.singleton((Attachment)item)); + break; + } + } + } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/IdeErrorsDialog.form b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/IdeErrorsDialog.form index f67b8c4a8c24..bda913ce86bd 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/errordialog/IdeErrorsDialog.form +++ b/platform/platform-impl/src/com/intellij/diagnostic/errordialog/IdeErrorsDialog.form @@ -90,17 +90,37 @@ - + - - - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties index 60c87bb1406c..661d6dafcb3a 100644 --- a/platform/platform-resources-en/src/messages/DiagnosticBundle.properties +++ b/platform/platform-resources-en/src/messages/DiagnosticBundle.properties @@ -90,3 +90,5 @@ error.dialog.attachment.path.column.title=Path error.dialog.attachment.include.column.title=Include error.attachments.tab.title=Attachments error.dialog.filecontent.title=File content +diagnostic.error.report.include.attachment.warning=Report will include attachment: ''{0}''. +diagnostic.error.report.include.attachments.warning=Report will include {0} attachments. diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 679fb01392fd..8f16cfe5b38d 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -485,6 +485,7 @@ +