/* Copyright (c) 2010, skobbler GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package org.openstreetmap.josm.plugins.mapdust.gui.component.panel; import java.awt.BorderLayout; import java.awt.Color; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.border.LineBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.plugins.mapdust.MapdustPlugin; import org.openstreetmap.josm.plugins.mapdust.gui.MapdustGUI; import org.openstreetmap.josm.plugins.mapdust.gui.action.adapter.DisplayMenu; import org.openstreetmap.josm.plugins.mapdust.gui.action.show.MapdustShowAction; import org.openstreetmap.josm.plugins.mapdust.gui.action.show.ShowCloseBugAction; import org.openstreetmap.josm.plugins.mapdust.gui.action.show.ShowCommentBugAction; import org.openstreetmap.josm.plugins.mapdust.gui.action.show.ShowInvalidateBugAction; import org.openstreetmap.josm.plugins.mapdust.gui.action.show.ShowReOpenBugAction; import org.openstreetmap.josm.plugins.mapdust.gui.component.model.BugsListModel; import org.openstreetmap.josm.plugins.mapdust.gui.component.renderer.BugListCellRenderer; import org.openstreetmap.josm.plugins.mapdust.gui.component.util.ComponentUtil; import org.openstreetmap.josm.plugins.mapdust.gui.observer.MapdustBugDetailsObservable; import org.openstreetmap.josm.plugins.mapdust.gui.observer.MapdustBugDetailsObserver; import org.openstreetmap.josm.plugins.mapdust.service.value.MapdustBug; /** * Defines the components of the MapDust bug list panel. * * @author Bea * @version $Revision$ */ public class MapdustBugListPanel extends JPanel implements ListSelectionListener, MapdustBugDetailsObservable { /** The serial version UID */ private static final long serialVersionUID = -675120506597637085L; /** The list of observers */ private final ArrayList<MapdustBugDetailsObserver> observers = new ArrayList<>(); /** The list of <code>MapdustBug</code> objects */ private List<MapdustBug> mapdustBugsList; /** The list of bugs */ private JList<MapdustBug> mapdustBugsJList; /** The scroll pane for the <code>MapdustBug</code>s */ private JScrollPane cmpMapdustBugs; /** The button panel */ private MapdustButtonPanel btnPanel; /** The <code>MapdustGUI</code> */ private MapdustGUI mapdustGUI; /** The pop-up menu */ private JPopupMenu menu; /** The add comment menu item */ private JMenuItem menuAddComment; /** The fixed menu item */ private JMenuItem menuFixed; /** The invalidate menu item */ private JMenuItem menuInvalidate; /** The re-open menu item */ private JMenuItem menuReopen; /** * Builds a <code>MapdustPlugin</code> object */ public MapdustBugListPanel() {} /** * Builds a <code>MapdustPlugin</code> object with the given parameters. * * @param mapdustBugsList The list of <code>MapdustBug</code> objects * @param name The name of the panel * @param mapdustPlugin The <code>MapdustPlugin</code> object */ public MapdustBugListPanel(List<MapdustBug> mapdustBugsList, String name, MapdustPlugin mapdustPlugin) { this.mapdustGUI = mapdustPlugin.getMapdustGUI(); this.mapdustBugsList = mapdustBugsList; setLayout(new BorderLayout(5, 10)); addComponents(mapdustPlugin); setName(name); } /** * Adds the components to the MapDust panel. * * @param mapdustPlugin The <code>MapdustPlugin</code> object */ private void addComponents(MapdustPlugin mapdustPlugin) { /* create components */ if (btnPanel == null) { btnPanel = new MapdustButtonPanel(mapdustPlugin); } if (menu == null) { menu = new JPopupMenu(); /* add comment item */ MapdustShowAction action = new ShowCommentBugAction(mapdustPlugin); menuAddComment = ComponentUtil.createJMenuItem(action, "Add comment/additional info", "dialogs/comment.png"); menu.add(menuAddComment); /* fix bug item */ action = new ShowCloseBugAction(mapdustPlugin); menuFixed = ComponentUtil.createJMenuItem(action, "Mark as fixed", "dialogs/fixed.png"); menu.add(menuFixed); /* invalidate bug item */ action = new ShowInvalidateBugAction(mapdustPlugin); menuInvalidate = ComponentUtil.createJMenuItem(action, "Non-reproducible/Software bug", "dialogs/invalid.png"); menu.add(menuInvalidate); /* re-open bug item */ action = new ShowReOpenBugAction(mapdustPlugin); menuReopen = ComponentUtil.createJMenuItem(action, "Reopen bug", "dialogs/reopen.png"); menu.add(menuReopen); } /* create bugs list */ if (mapdustBugsList == null || mapdustBugsList.isEmpty()) { String text = " No bugs in the current view for the selected"; text += " filters!"; JList<String> textJList = new JList<>(new String[] {text}); textJList.setBorder(new LineBorder(Color.black, 1, false)); textJList.setCellRenderer(new BugListCellRenderer()); cmpMapdustBugs = ComponentUtil.createJScrollPane(textJList); add(cmpMapdustBugs, BorderLayout.CENTER); } else { mapdustBugsJList = ComponentUtil.createJList(mapdustBugsList, menu); mapdustBugsJList.addListSelectionListener(this); DisplayMenu adapter = new DisplayMenu(mapdustBugsJList, menu); mapdustBugsJList.addMouseListener(adapter); cmpMapdustBugs = ComponentUtil.createJScrollPane(mapdustBugsJList); add(cmpMapdustBugs, BorderLayout.CENTER); } /* add button panel */ add(btnPanel, BorderLayout.SOUTH); } /** * Updates the <code>MapdustPanel</code> with the new list of * <code>MapdustBug</code>s. If the list is null or empty an appropriate * message will be displayed on the list. * * @param mapdustBugsList The list of <code>MapdustBug</code>s */ public synchronized void updateComponents(List<MapdustBug> mapdustBugsList) { this.mapdustBugsList = mapdustBugsList; if (mapdustBugsList == null || mapdustBugsList.isEmpty()) { String text = " No bugs in the current view for the selected"; text += " filters!"; JList<String> textJList = new JList<>(new String[] {text}); textJList.setBorder(new LineBorder(Color.black, 1, false)); textJList.setCellRenderer(new BugListCellRenderer()); cmpMapdustBugs.getViewport().setView(textJList); } else { if (mapdustBugsJList == null) { mapdustBugsJList = ComponentUtil.createJList(mapdustBugsList, menu); mapdustBugsJList.addListSelectionListener(this); DisplayMenu adapter = new DisplayMenu(mapdustBugsJList, menu); mapdustBugsJList.addMouseListener(adapter); } else { mapdustBugsJList.setModel(new BugsListModel(mapdustBugsList)); } cmpMapdustBugs.getViewport().setView(mapdustBugsJList); } } /** * Listens to the <code>ListSelectionEvent</code>s and modifies the buttons * and menu items depending on the status of the <code>MapdustBug</code> * object. * * @param event The <code>ListSelectionEvent</code> object */ @Override public synchronized void valueChanged(ListSelectionEvent event) { if (!event.getValueIsAdjusting()) { MapdustBug selectedBug = (MapdustBug) mapdustBugsJList.getSelectedValue(); if (selectedBug != null) { Main.pref.put("selectedBug.status", selectedBug.getStatus() .getValue()); if (selectedBug.getStatus().getKey().equals(1)) { /* status open */ btnPanel.getBtnAddComment().setEnabled(true); btnPanel.getBtnReOpenBugReport().setEnabled(false); btnPanel.getBtnInvalidateBugReport().setEnabled(true); btnPanel.getBtnFixBugReport().setEnabled(true); getMenuReopen().setEnabled(false); getMenuInvalidate().setEnabled(true); getMenuFixed().setEnabled(true); } if (selectedBug.getStatus().getKey().equals(2)) { /* status fixed */ btnPanel.getBtnAddComment().setEnabled(true); btnPanel.getBtnReOpenBugReport().setEnabled(true); btnPanel.getBtnInvalidateBugReport().setEnabled(false); btnPanel.getBtnFixBugReport().setEnabled(false); getMenuReopen().setEnabled(true); getMenuInvalidate().setEnabled(false); getMenuFixed().setEnabled(false); } if (selectedBug.getStatus().getKey().equals(3)) { /* status invalid */ btnPanel.getBtnAddComment().setEnabled(true); btnPanel.getBtnReOpenBugReport().setEnabled(true); btnPanel.getBtnInvalidateBugReport().setEnabled(false); btnPanel.getBtnFixBugReport().setEnabled(false); getMenuReopen().setEnabled(true); getMenuInvalidate().setEnabled(false); getMenuFixed().setEnabled(false); } btnPanel.getBtnAddComment().setSelected(false); btnPanel.getBtnReOpenBugReport().setSelected(false); btnPanel.getBtnFixBugReport().setSelected(false); btnPanel.getBtnInvalidateBugReport().setSelected(false); notifyObservers(selectedBug); } else { btnPanel.getBtnWorkOffline().setSelected(false); btnPanel.getBtnWorkOffline().setFocusable(false); btnPanel.getBtnRefresh().setSelected(false); btnPanel.getBtnRefresh().setFocusable(false); btnPanel.getBtnFilter().setSelected(false); btnPanel.getBtnFilter().setFocusable(false); btnPanel.getBtnAddComment().setEnabled(false); btnPanel.getBtnFixBugReport().setEnabled(false); btnPanel.getBtnInvalidateBugReport().setEnabled(false); btnPanel.getBtnReOpenBugReport().setEnabled(false); } /* re-paint */ Main.map.mapView.repaint(); mapdustGUI.repaint(); } else { return; } } /** * Returns the selected bug from the list of MapDust bugs. * * @return a <code>MapdustBug</code> object */ public MapdustBug getSelectedBug() { MapdustBug selectedBug = null; if (getMapdustBugsJList() != null) { selectedBug = (MapdustBug) getMapdustBugsJList().getSelectedValue(); } return selectedBug; } /** * Sets the <code>MapdustBug</code> which will be selected from the list of * MapDust bug. * * @param mapdustBug The <code>MapdustBug</code> object */ public void setSelectedBug(MapdustBug mapdustBug) { mapdustBugsJList.setSelectedValue(mapdustBug, false); int index = mapdustBugsJList.getSelectedIndex(); mapdustBugsJList.ensureIndexIsVisible(index); } /** * Selects the <code>MapdustBug</code> at the given index. * * @param index The index of the <code>MapdustBug</code> */ public void resetSelectedBug(int index) { if (mapdustBugsJList != null) { mapdustBugsJList.setSelectedIndex(index); } } /** * Returns the selected <code>MapdustBug</code> object index. * * @return index */ public int getSelectedBugIndex() { return mapdustBugsJList.getSelectedIndex(); } /** * Disables the buttons from the <code>MapdustButtonPanel</code>. */ public void disableBtnPanel() { btnPanel.disableComponents(); } /** * Enables the basic components from the <code>MapdustButtonPanel</code>. * Basic components are considered the following buttons: work offline, * filter bug report, and refresh.If the onlyBasic flag is true then the * other buttons will be disabled. * * @param onlyBasic If true then the not basic buttons will be disabled */ public void enableBtnPanel(boolean onlyBasic) { btnPanel.enableBasicComponents(onlyBasic); } /** * Returns the list of bugs * * @return the listBugs */ public JList<MapdustBug> getMapdustBugsJList() { return mapdustBugsJList; } /** * Return the menu * * @return the menu */ public JPopupMenu getMenu() { return menu; } /** * Returns the button panel * * @return the btnPanel */ public MapdustButtonPanel getBtnPanel() { return btnPanel; } /** * Returns the 'add comment' menu item * * @return the menuAddComment */ public JMenuItem getMenuAddComment() { return menuAddComment; } /** * Returns the 'fixed' menu item * * @return the menuFixed */ public JMenuItem getMenuFixed() { return menuFixed; } /** * Returns the 'invalidate' menu item * * @return the menuInvalidate */ public JMenuItem getMenuInvalidate() { return menuInvalidate; } /** * Returns the 're-open' menu item * * @return the menuReopen */ public JMenuItem getMenuReopen() { return menuReopen; } /** * Returns the list of <code>MapdustBug</code> objects * * @return the mapdustBugsList */ public List<MapdustBug> getMapdustBugsList() { return mapdustBugsList; } /** * Adds a new MapDust bug details observer to the list of observers. * * @param observer The <code>MapdustBugDetailsObserver</code> object */ @Override public void addObserver(MapdustBugDetailsObserver observer) { if (!this.observers.contains(observer)) { this.observers.add(observer); } } /** * Removes the given MapDust bug details observer from the list of * observers. * * @param observer The <code>MapdustBugDetailsObserver</code> object */ @Override public void removeObserver(MapdustBugDetailsObserver observer) { this.observers.remove(observer); } /** * Notifies the MapDust bug details observers observing the given * <code>MapdustBug</code> object. * * @param mapdustBug The <code>MapdustBug</code> object */ @Override public void notifyObservers(MapdustBug mapdustBug) { Iterator<MapdustBugDetailsObserver> elements = this.observers.iterator(); while (elements.hasNext()) { (elements.next()).showDetails(mapdustBug); } } }