/* * 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.content.detail; import com.hp.alm.ali.idea.rest.RestService; import com.hp.alm.ali.idea.rest.ServerType; import com.hp.alm.ali.idea.rest.ServerTypeListener; import com.hp.alm.ali.idea.model.Entity; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.JBCheckboxMenuItem; import com.intellij.openapi.util.IconLoader; import com.intellij.util.ui.UIUtil; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JToggleButton; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; public class PageBar extends JPanel implements ServerTypeListener { private List<MyContentButton> components; private ButtonGroup group; private ExtraContent extraContent; private JToggleButton unselector; private RestService restService; private boolean reloadNeeded; private Entity entity; private JPanel centerPanel; private JButton moreLink; public PageBar(Project project, Entity entity) { super(new GridBagLayout()); this.entity = entity; createCenterPanelAndMoreLink(); components = new LinkedList<MyContentButton>(); group = new ButtonGroup(); unselector = new JToggleButton(); group.add(unselector); restService = project.getComponent(RestService.class); initialize(); restService.addServerTypeListener(this); } public int getPreferredHeightWhenExpanded() { return Collections.max(components, new Comparator<JComponent>() { @Override public int compare(JComponent o1, JComponent o2) { return o1.getPreferredSize().height - o2.getPreferredSize().height; } }).getPreferredSize().height; } public void markForReload() { reloadNeeded = true; } public void reloadIfNeeded() { if(reloadNeeded) { reload(); } } private void createCenterPanelAndMoreLink() { centerPanel = new JPanel(new ProxyFlowLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.anchor = GridBagConstraints.WEST; c.weightx = 1; add(centerPanel, c); moreLink = new JButton(IconLoader.getIcon("/ide/link.png")); moreLink.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); moreLink.addActionListener(new MoreLinkActionListener()); moreLink.setVisible(false); ++c.gridx; c.anchor = GridBagConstraints.NORTHEAST; c.weightx = 0; add(moreLink, c); } private void removeExistingComponents() { for(MyContentButton contentButton: components) { group.remove(contentButton); contentButton.getContent().remove(); remove(contentButton); } components.clear(); } public void remove() { restService.removeServerTypeListener(this); removeExistingComponents(); } public void initialize() { removeExistingComponents(); List<DetailContent> list = restService.getServerStrategy().getDetailContent(entity); for(DetailContent content: list) { addContent(content); } revalidate(); repaint(); reloadNeeded = true; } public void reload() { reloadNeeded = false; setVisible(true); for(MyContentButton contentButton: components) { contentButton.getContent().reload(); } } public void setVisible(boolean visible) { super.setVisible(visible); extraContent.setVisible(visible); } public void addContent(final DetailContent content) { final MyContentButton contentButton = new MyContentButton(content, null, content.getIcon()); components.add(contentButton); group.add(contentButton); contentButton.setFocusable(false); contentButton.addActionListener(new ToggleListener(contentButton)); contentButton.getContent().addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { contentButton.setEnabled(content.getComponent() != null && restService.getServerTypeIfAvailable().isConnected()); contentButton.setText(content.getLinkText()); } }); } }); contentButton.setEnabled(content.getComponent() != null && restService.getServerTypeIfAvailable().isConnected()); contentButton.setText(content.getLinkText()); centerPanel.add(contentButton); } public void setExtraContent(ExtraContent extraContent) { this.extraContent = extraContent; } @Override public void connectedTo(final ServerType serverType) { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { boolean connected = serverType.isConnected(); if(!connected) { group.clearSelection(); } for(MyContentButton button: components) { if(!connected) { extraContent.hideComponent(button.getContent().getComponent()); } button.setEnabled(connected); } } }); } private class ToggleListener implements ActionListener { private MyContentButton contentButton; public ToggleListener(MyContentButton contentButton) { this.contentButton = contentButton; } public void actionPerformed(ActionEvent actionEvent) { if(!extraContent.toggleComponent(contentButton.getContent().getComponent())) { unselector.setSelected(true); } else { contentButton.setSelected(true); } } } private static class MyContentButton extends JToggleButton { private DetailContent content; public MyContentButton(DetailContent content, String label, Icon icon) { super(label, icon); this.content = content; } public DetailContent getContent() { return content; } } private class MoreLinkActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { final JPopupMenu menu = new JPopupMenu(); int n = centerPanel.getComponentCount(); if (n > 1) { Component firstComponent = centerPanel.getComponent(0); for (int i = 1; i < n; i++) { final MyContentButton component = (MyContentButton) centerPanel.getComponent(i); if (component.getY() > firstComponent.getY()) { JBCheckboxMenuItem item = new JBCheckboxMenuItem(component.getText()); item.setState(component.isSelected()); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { menu.setVisible(false); new ToggleListener(component).actionPerformed(e); } }); menu.add(item); } } } menu.show(PageBar.this, moreLink.getX(), moreLink.getY()); } } private class ProxyFlowLayout extends FlowLayout { private ProxyFlowLayout() { super(FlowLayout.LEFT); } @Override public void layoutContainer(Container target) { super.layoutContainer(target); int n = centerPanel.getComponentCount(); if (n > 1) { if (centerPanel.getComponent(n - 1).getY() > centerPanel.getComponent(0).getY()) { if (!moreLink.isVisible()) { moreLink.setVisible(true); // if the resize event is small enough, the link wouldn't (sometimes) show until next event SwingUtilities.invokeLater(new Runnable() { @Override public void run() { PageBar.this.revalidate(); PageBar.this.repaint(); } }); } return; } } moreLink.setVisible(false); } } }