/* * Copyright 2013 Hewlett-Packard Development Company, L.P * * 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.hp.alm.ali.idea.ui.entity; import com.hp.alm.ali.idea.entity.EntityStatusIndicator; import com.hp.alm.ali.idea.model.Entity; import com.hp.alm.ali.idea.ui.dialog.ErrorDialog; import com.hp.alm.ali.idea.ui.dialog.RestErrorDetailDialog; import com.hp.alm.ali.idea.model.parser.EntityList; import com.hp.alm.ali.idea.rest.RestException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.ui.components.labels.LinkLabel; import com.intellij.ui.components.labels.LinkListener; import com.intellij.util.ui.UIUtil; import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.Border; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Insets; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; public class EntityStatusPanel extends JPanel implements EntityStatusIndicator, LinkListener { private static Icon redoIcon = IconLoader.getIcon("/actions/sync.png"); private static Icon detailsIcon = IconLoader.getIcon("/general/error.png"); private JLabel icon; private JLabel message; private LinkLabel detail; private LinkLabel moreLink; private Exception exception; private Runnable more; private Runnable redo; public EntityStatusPanel(final Project project) { super(new FlowLayout(FlowLayout.LEFT, 3, 0)); setOpaque(false); icon = new LinkLabel(); message = new JLabel(""); detail = new LinkLabel("", detailsIcon, new LinkListener() { public void linkSelected(LinkLabel aSource, Object aLinkData) { if(exception instanceof RestException) { new RestErrorDetailDialog(project, exception).setVisible(true); } else { StringWriter sw = new StringWriter(); exception.printStackTrace(new PrintWriter(sw)); new ErrorDialog(exception.getMessage() == null? exception.getClass().getSimpleName(): exception.getMessage(), sw.toString()).setVisible(true); } } }, null); moreLink = new LinkLabel("(load more)", null, new LinkListener() { @Override public void linkSelected(LinkLabel aSource, Object aLinkData) { moreLink.setVisible(false); more.run(); } }, null); moreLink.setVisible(false); add(message); add(moreLink); } @Override public void loading() { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { setIcon(null); handleException(null); handleMore(null); message.setText("Loading information..."); } }); } @Override public void loaded(final EntityList data, Runnable redo) { info("Loaded " + getItemCountString(data, "items"), null, redo, null); } @Override public void clear() { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { message.setText(""); handleRedo(null); handleException(null); handleMore(null); } }); } @Override public void info(final String msg, final Exception e, final Runnable redo, final Runnable more) { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { message.setText(msg); handleRedo(redo); handleException(e); handleMore(more); } }); } public static String getItemCountString(EntityList data, String name) { return getItemCountString(data.getTotal(), data, name); } public static String getItemCountString(int total, List<Entity> data, String name) { return getItemCountString(total, data.size(), name); } public static String getItemCountString(int total, int n, String name) { if (total > n) { return n + " " + name + " out of " + total; } else { return n + " " + name; } } private void setIcon(Icon i) { if(icon.getParent() != null) { if(i != null && i.equals(icon.getIcon())) { return; } remove(icon); } if(i != null) { icon = new LinkLabel("", i, this, null); add(icon, 0); } } private void handleException(Exception e) { this.exception = e; if(e != null) { if(detail.getParent() == null) { add(detail); } } else { if(detail.getParent() != null) { remove(detail); } } } private void handleRedo(Runnable redo) { this.redo = redo; if(redo != null) { setIcon(redoIcon); } else { setIcon(null); } } private void handleMore(Runnable more) { this.more = more; if (more != null) { moreLink.setVisible(true); } else { moreLink.setVisible(false); } } @Override public void linkSelected(LinkLabel aSource, Object aLinkData) { redo.run(); } @Override public Dimension getPreferredSize() { // avoid visual flicker caused by resizing when nothing/something is showing Dimension size = super.getPreferredSize(); Insets insets; Border border = getBorder(); if(border != null) { insets = border.getBorderInsets(this); } else { insets = new Insets(0, 0, 0, 0); } return new Dimension(size.width, Math.max(size.height, detailsIcon.getIconHeight() + insets.bottom + insets.top)); } }