/** * Copyright 2014 Microsoft Open Technologies Inc. * * 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.microsoftopentechnologies.intellij.activitylog; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowFactory; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.BrowserHyperlinkListener; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.table.TableView; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import com.intellij.util.ui.PlatformColors; import com.microsoftopentechnologies.azurecommons.deploy.DeploymentEventArgs; import com.microsoftopentechnologies.azurecommons.deploy.DeploymentEventListener; import com.microsoftopentechnologies.intellij.AzurePlugin; import com.microsoftopentechnologies.intellij.util.PluginUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.table.TableCellRenderer; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.font.TextAttribute; import java.io.IOException; import java.net.URI; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Locale; import java.util.Map; import static com.microsoftopentechnologies.intellij.ui.messages.AzureBundle.message; public class ActivityLogToolWindowFactory implements ToolWindowFactory { public static final String ACTIVITY_LOG_WINDOW = "Azure Activity Log"; private SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss", Locale.getDefault()); private TableView<DeploymentTableItem> table; private HashMap<String, DeploymentTableItem> rows = new HashMap<String, DeploymentTableItem>(); private Project project; @Override public void createToolWindowContent(@NotNull final Project project, @NotNull final ToolWindow toolWindow) { this.project = project; table = new TableView<DeploymentTableItem>(new ListTableModel<DeploymentTableItem>(DESC, PROGRESS, STATUS, START_TIME)); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // add mouse listener for links in table table.addMouseListener(createTableMouseListener()); toolWindow.getComponent().add(new JBScrollPane(table)); registerDeploymentListener(); } private MouseListener createTableMouseListener() { return new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (table.getSelectedColumn() == 2) { DeploymentTableItem item = table.getSelectedObject(); if (item != null && item.link != null) { try { Desktop.getDesktop().browse(URI.create(item.link)); } catch (IOException e1) { PluginUtil.displayErrorDialogAndLog(message("error"), message("error"), e1); } } } } }; } public void registerDeploymentListener() { AzurePlugin.addDeploymentEventListener( new DeploymentEventListener() { @Override public void onDeploymentStep(final DeploymentEventArgs args) { // unique identifier for deployment String key = args.getId() + args.getStartTime().getTime(); if (rows.containsKey(key)) { final DeploymentTableItem item = rows.get(key); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { item.progress += args.getDeployCompleteness(); if (args.getDeployMessage().equalsIgnoreCase(message("runStatus"))) { String html = String.format("%s%s%s%s", " ", "<html><a href=\"" + args.getDeploymentURL() + "\">", message("runStatusVisible"), "</a></html>"); item.description = message("runStatusVisible"); item.link = args.getDeploymentURL(); if (!ToolWindowManager.getInstance(project).getToolWindow(ActivityLogToolWindowFactory.ACTIVITY_LOG_WINDOW).isVisible()) { ToolWindowManager.getInstance(project).notifyByBalloon(ACTIVITY_LOG_WINDOW, MessageType.INFO, html, null, new BrowserHyperlinkListener()); } } else { item.description = args.getDeployMessage(); } table.getListTableModel().fireTableDataChanged(); } }); } else { final DeploymentTableItem item = new DeploymentTableItem(args.getId(), args.getDeployMessage(), dateFormat.format(args.getStartTime()), args.getDeployCompleteness()); rows.put(key, item); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { table.getListTableModel().addRow(item); } }); } } }); } private class ProgressBarRenderer implements TableCellRenderer { private final JProgressBar progressBar = new JProgressBar(); private final JLabel label = new JLabel(); public ProgressBarRenderer() { progressBar.setMaximum(100); } @Override public Component getTableCellRendererComponent(@NotNull JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if ((Integer) value < 100) { progressBar.setValue((Integer) value); return progressBar; } else { label.setText(""); return label; } } } private class LinkRenderer implements TableCellRenderer { private final JLabel label = new JLabel(); public LinkRenderer() { label.setForeground(PlatformColors.BLUE); Font font = label.getFont(); Map attributes = font.getAttributes(); attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); label.setFont(font.deriveFont(attributes)); } @Override public Component getTableCellRendererComponent(@NotNull JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { label.setText((String) value); return label; } } private final ColumnInfo<DeploymentTableItem, String> DESC = new ColumnInfo<DeploymentTableItem, String>(message("desc")) { public String valueOf(DeploymentTableItem object) { return object.deploymentId; } }; private final ColumnInfo<DeploymentTableItem, Integer> PROGRESS = new ColumnInfo<DeploymentTableItem, Integer>("Progress") { private TableCellRenderer renderer = new ProgressBarRenderer(); public Integer valueOf(DeploymentTableItem object) { return object.progress; } public TableCellRenderer getRenderer(DeploymentTableItem object) { return renderer; } }; private final ColumnInfo<DeploymentTableItem, String> STATUS = new ColumnInfo<DeploymentTableItem, String>(message("status")) { private TableCellRenderer renderer = new LinkRenderer(); public String valueOf(DeploymentTableItem object) { return object.description; } public TableCellRenderer getRenderer(DeploymentTableItem object) { if (object.link != null) { return renderer; } else { return super.getRenderer(object); } } }; private final ColumnInfo<DeploymentTableItem, String> START_TIME = new ColumnInfo<DeploymentTableItem, String>(message("startTime")) { public String valueOf(DeploymentTableItem object) { return object.startDate; } }; private class DeploymentTableItem { private String deploymentId; private String description; private String startDate; private String link; private int progress; public DeploymentTableItem(String deploymentId, String description, String startDate, int progress) { this.deploymentId = deploymentId; this.description = description; this.startDate = startDate; this.progress = progress; } } }