/* *------------------------------------------------------------------------------ * Copyright (C) 2015-2016 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.metadata.editor; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.swing.JButton; import omero.gateway.model.AnnotationData; import omero.gateway.model.DataObject; import omero.gateway.model.TagAnnotationData; import org.openmicroscopy.shoola.agents.metadata.IconManager; import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.WrapLayout; /** * A {@link AnnotationTaskPaneUI} for displaying {@link TagAnnotationData} * * @author Dominik Lindner      <a * href="mailto:d.lindner@dundee.ac.uk">d.lindner@dundee.ac.uk</a> */ public class TagsTaskPaneUI extends AnnotationTaskPaneUI { /** Hold the {@link DocComponent}s representing the tag data */ private List<DocComponent> tagsDocList; /** The add button */ private JButton addTagsButton; /** The remove button */ private JButton removeTagsButton; /** Tags which have to be removed */ private List<TagAnnotationData> toRemove = new ArrayList<TagAnnotationData>(); /** Tags which have to be stored */ private List<TagAnnotationData> toAdd = new ArrayList<TagAnnotationData>(); /** * Creates a new instance * * @param model * Reference to the {@link EditorModel} * @param view * Reference to the {@link EditorUI} * @param controller * Reference to the {@link EditorControl} */ TagsTaskPaneUI(EditorModel model, EditorUI view, EditorControl controller) { super(model, view, controller); setLayout(new WrapLayout(WrapLayout.LEFT)); setBackground(UIUtilities.BACKGROUND_COLOR); tagsDocList = new ArrayList<DocComponent>(); } @Override void clearDisplay() { removeAll(); tagsDocList.clear(); } /** * Lays out the tags. * * @param list The collection of tags to layout. */ private void layoutTags(Collection list) { removeAll(); tagsDocList.clear(); DocComponent doc; filter(list); if (list != null && list.size() > 0) { Iterator i = list.iterator(); DataObject data; switch (filter) { case SHOW_ALL: while (i.hasNext()) { doc = new DocComponent(i.next(), model); doc.addPropertyChangeListener(controller); tagsDocList.add(doc); add(doc); } break; case ADDED_BY_ME: while (i.hasNext()) { data = (DataObject) i.next(); if (model.isLinkOwner(data)) { doc = new DocComponent(data, model); doc.addPropertyChangeListener(controller); tagsDocList.add(doc); add(doc); } } break; case ADDED_BY_OTHERS: while (i.hasNext()) { data = (DataObject) i.next(); if (model.isAnnotatedByOther(data)) { doc = new DocComponent(data, model); doc.addPropertyChangeListener(controller); tagsDocList.add(doc); add(doc); } } } } if (tagsDocList.size() == 0) { doc = new DocComponent(null, model); tagsDocList.add(doc); add(doc); } } /** * Removes duplicate entries from the collection * * @param collection */ void filter(Collection collection) { Set<Long> ids = new HashSet<Long>(); Iterator it = collection.iterator(); while (it.hasNext()) { long id = ((DataObject) it.next()).getId(); if (ids.contains(id)) { it.remove(); continue; } ids.add(id); } } @Override void refreshUI() { clearDisplay(); toAdd.clear(); toRemove.clear(); Collection l; if (!model.isMultiSelection()) l = model.getTags(); else l = model.getAllTags(); layoutTags(l); addTagsButton.setEnabled(model.canAddAnnotationLink()); removeTagsButton.setEnabled(model.canAddAnnotationLink()); } /** * Returns the collection of tags. * * @return See above. */ List<TagAnnotationData> removeTags() { List<TagAnnotationData> list = new ArrayList<TagAnnotationData>(); if (tagsDocList.size() == 0) { return list; } List<TagAnnotationData> toKeep = new ArrayList<TagAnnotationData>(); TagAnnotationData data; DocComponent doc; Object object; Iterator<DocComponent> i = tagsDocList.iterator(); while (i.hasNext()) { doc = i.next(); object = doc.getData(); if (doc.canUnlink()) { if (object instanceof TagAnnotationData) { data = (TagAnnotationData) object; if (data.getId() > 0) list.add(data); } } else { toKeep.add((TagAnnotationData) object); } } handleObjectsSelection(TagAnnotationData.class, toKeep, false); return list; } /** * Handles the selection of objects via the selection wizard. * * @param type The type of objects to handle. * @param objects The objects to handle. * @param fire Pass <code>true</code> to notify, <code>false</code> * otherwise. */ void handleObjectsSelection(Class<?> type, Collection objects, boolean fire) { toAdd.clear(); toRemove.clear(); Set<Long> selectedIds = new HashSet<Long>(); for(Object obj : objects) { if(obj instanceof TagAnnotationData) { selectedIds.add(((TagAnnotationData)obj).getId()); } } // determine which tags to remove Set<Long> originalIds = new HashSet<Long>(); Collection<TagAnnotationData> originalTags = model.getAllTags(); for(TagAnnotationData originalTag : originalTags) { if(!selectedIds.contains(originalTag.getId())) toRemove.add(originalTag); originalIds.add(originalTag.getId()); } // determine which tags to add for(Object obj : objects) { if(obj instanceof TagAnnotationData) { TagAnnotationData tag = (TagAnnotationData)obj; if(!originalIds.contains(tag.getId())) toAdd.add(tag); } } layoutTags(objects); } @Override List<JButton> getToolbarButtons() { List<JButton> buttons = new ArrayList<JButton>(); IconManager icons = IconManager.getInstance(); addTagsButton = new JButton(icons.getIcon(IconManager.PLUS_12)); UIUtilities.unifiedButtonLookAndFeel(addTagsButton); addTagsButton.setBackground(UIUtilities.BACKGROUND_COLOR); addTagsButton.setToolTipText("Add Tags."); addTagsButton.addActionListener(controller); addTagsButton.setActionCommand(""+EditorControl.ADD_TAGS); buttons.add(addTagsButton); removeTagsButton = new JButton(icons.getIcon(IconManager.MINUS_12)); UIUtilities.unifiedButtonLookAndFeel(removeTagsButton); removeTagsButton.setBackground(UIUtilities.BACKGROUND_COLOR); removeTagsButton.setToolTipText("Remove Tags."); removeTagsButton.addMouseListener(controller); removeTagsButton.setActionCommand(""+EditorControl.REMOVE_TAGS); buttons.add(removeTagsButton); return buttons; } @Override List<AnnotationData> getAnnotationsToSave() { return new ArrayList<AnnotationData>(toAdd); } @Override List<Object> getAnnotationsToRemove() { return new ArrayList<Object>(toRemove); } List<TagAnnotationData> getCurrentSelection() { List<TagAnnotationData> result = new ArrayList<TagAnnotationData>(); for(DocComponent c : tagsDocList) result.add((TagAnnotationData)c.getData()); return result; } /** * Returns <code>true</code> some tags can be unlinked, * <code>false</code> otherwise. * * @return See above. */ boolean hasTagsToUnlink() { if (tagsDocList.size() == 0) return false; DocComponent doc; Object object; Iterator<DocComponent> i = tagsDocList.iterator(); while (i.hasNext()) { doc = i.next(); object = doc.getData(); if (doc.canUnlink()) { if (object instanceof TagAnnotationData) { return true; } } } return false; } @Override void onRelatedNodesSet() { addTagsButton.setEnabled(model.canAddAnnotationLink()); removeTagsButton.setEnabled(model.canDeleteAnnotationLink()); } }