001    /*
002     * The contents of this file are subject to the Mozilla Public
003     * License Version 1.1 (the "License"); you may not use this file
004     * except in compliance with the License. You may obtain a copy of
005     * the License at http://www.mozilla.org/MPL/
006     *
007     * Software distributed under the License is distributed on an "AS
008     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
009     * implied. See the License for the specific language governing
010     * rights and limitations under the License.
011     *
012     * The Original Code is Knowtator.
013     *
014     * The Initial Developer of the Original Code is University of Colorado.  
015     * Copyright (C) 2005-2008.  All Rights Reserved.
016     *
017     * Knowtator was developed by the Center for Computational Pharmacology
018     * (http://compbio.uchcs.edu) at the University of Colorado Health 
019     *  Sciences Center School of Medicine with support from the National 
020     *  Library of Medicine.  
021     *
022     * Current information about Knowtator can be obtained at 
023     * http://knowtator.sourceforge.net/
024     *
025     * Contributor(s):
026     *   Philip V. Ogren <philip@ogren.info> (Original Author)
027     */
028    package edu.uchsc.ccp.knowtator.ui;
029    
030    import java.awt.event.ActionEvent;
031    import java.awt.event.ActionListener;
032    import java.awt.event.MouseAdapter;
033    import java.awt.event.MouseEvent;
034    import java.awt.event.MouseListener;
035    import java.util.Collection;
036    import java.util.List;
037    
038    import javax.swing.Action;
039    import javax.swing.JMenuItem;
040    import javax.swing.JPopupMenu;
041    import javax.swing.tree.TreeNode;
042    import javax.swing.tree.TreePath;
043    
044    import org.apache.log4j.Logger;
045    
046    import edu.stanford.smi.protege.event.FrameAdapter;
047    import edu.stanford.smi.protege.event.FrameEvent;
048    import edu.stanford.smi.protege.model.Cls;
049    import edu.stanford.smi.protege.model.Frame;
050    import edu.stanford.smi.protege.model.KnowledgeBase;
051    import edu.stanford.smi.protege.model.ModelUtilities;
052    import edu.stanford.smi.protege.model.SimpleInstance;
053    import edu.stanford.smi.protege.model.Slot;
054    import edu.stanford.smi.protege.ui.ParentChildRoot;
055    import edu.stanford.smi.protege.util.ComponentUtilities;
056    import edu.stanford.smi.protege.util.LazyTreeNode;
057    import edu.stanford.smi.protege.util.LazyTreeRoot;
058    import edu.stanford.smi.protege.util.Selectable;
059    import edu.stanford.smi.protege.util.SelectableTree;
060    import edu.stanford.smi.protege.util.SelectionListener;
061    import edu.uchsc.ccp.knowtator.AnnotationUtil;
062    import edu.uchsc.ccp.knowtator.BrowserTextUtil;
063    import edu.uchsc.ccp.knowtator.KnowtatorManager;
064    import edu.uchsc.ccp.knowtator.KnowtatorProjectUtil;
065    import edu.uchsc.ccp.knowtator.MentionUtil;
066    import edu.uchsc.ccp.knowtator.ProjectSettings;
067    import edu.uchsc.ccp.knowtator.TextSourceUtil;
068    import edu.uchsc.ccp.knowtator.event.EventHandler;
069    import edu.uchsc.ccp.knowtator.event.RefreshAnnotationsDisplayListener;
070    import edu.uchsc.ccp.knowtator.event.SelectedAnnotationChangeEvent;
071    import edu.uchsc.ccp.knowtator.event.SelectedAnnotationChangeListener;
072    
073    public class AnnotationSchemaTree extends SelectableTree implements SelectedAnnotationChangeListener,
074                    SelectionListener, RefreshAnnotationsDisplayListener {
075            public void refreshAnnotationsDisplay(boolean scrollToSelection) {
076                    validate();
077                    repaint();
078            }
079    
080            static final long serialVersionUID = 0;
081    
082            KnowtatorManager manager;
083    
084            KnowledgeBase kb;
085    
086            AnnotationUtil annotationUtil;
087    
088            MentionUtil mentionUtil;
089    
090            KnowtatorProjectUtil kpu;
091    
092            TextSourceUtil textSourceUtil;
093    
094            BrowserTextUtil browserTextUtil;
095    
096            ColorFrameRenderer renderer;
097    
098            JPopupMenu popupMenu;
099    
100            Logger logger = Logger.getLogger(AnnotationSchemaTree.class);
101    
102            public AnnotationSchemaTree(KnowtatorManager manager, Action doubleClickAction, LazyTreeRoot root) {
103                    super(doubleClickAction, root);
104    
105                    initialize(manager);
106            }
107    
108            private void initialize(KnowtatorManager manager) {
109                    this.manager = manager;
110                    mentionUtil = manager.getMentionUtil();
111                    annotationUtil = manager.getAnnotationUtil();
112                    kpu = manager.getKnowtatorProjectUtil();
113                    textSourceUtil = manager.getTextSourceUtil();
114                    browserTextUtil = manager.getBrowserTextUtil();
115                    renderer = manager.getRenderer();
116    
117                    popupMenu = new JPopupMenu();
118    
119                    setLargeModel(true);
120                    // setRowHeight(rootCls.getIcon().getIconHeight());
121                    setSelectionRow(0);
122                    setAutoscrolls(true);
123                    setCellRenderer(renderer);
124                    addSelectionListener(this);
125                    addMouseListener(createSelectableListener());
126    
127                    SimpleInstance configuration = ProjectSettings.getActiveConfiguration(kpu.getKnowledgeBase().getProject());
128                    configuration.addFrameListener(new FrameAdapter() {
129                            public void ownSlotValueChanged(FrameEvent frameEvent) {
130                                    Slot slot = frameEvent.getSlot();
131                                    if (slot.equals(kpu.getRootClsesSlot())) {
132                                            setRoot(new ParentChildRoot(AnnotationSchemaTree.this.manager.getRootClses()));
133                                    }
134                            }
135                    });
136    
137                    EventHandler.getInstance().addSelectedAnnotationChangeListener(this);
138                    EventHandler.getInstance().addRefreshAnnotationsDisplayListener(this);
139            }
140    
141            public void annotationSelectionChanged(SelectedAnnotationChangeEvent sace) {
142                    SimpleInstance selectedAnnotation = sace.getSelectedAnnotation();
143                    if (selectedAnnotation == null)
144                            return;
145    
146                    SimpleInstance selectedMention = annotationUtil.getMention(selectedAnnotation);
147    
148                    logger.debug("selected annotation = \"" + browserTextUtil.getBrowserText(selectedAnnotation, 100));
149                    mentionUtil.initializeSlotMentions(selectedMention);
150    
151                    Cls selectedCls = mentionUtil.getMentionCls(selectedMention);
152    
153                    if (selectedCls != null) {
154                            java.util.List path = ModelUtilities.getPathToRoot(selectedCls);
155                            List<Cls> rootClses = manager.getRootClses();
156                            if (rootClses.size() > 0) {
157                                    boolean baseOfPathFound = false;
158                                    while (!baseOfPathFound && path.size() > 0) {
159                                            for (Cls rootCls : rootClses) {
160                                                    if (rootCls.equals(path.get(0))) {
161                                                            baseOfPathFound = true;
162                                                    }
163                                            }
164                                            if (!baseOfPathFound)
165                                                    path.remove(0);
166                                    }
167                                    if (path.size() > 0)
168                                            ComponentUtilities.setSelectedObjectPath(this, path);
169                            }
170                    }
171    
172            }
173    
174            public void selectionChanged(edu.stanford.smi.protege.util.SelectionEvent selectionEvent) {
175                    Selectable selectable = selectionEvent.getSelectable();
176                    Collection selection = selectable.getSelection();
177    
178                    if (selection.size() == 1) {
179                            Cls selectedCls = (Cls) selection.iterator().next();
180                            logger.debug("selected cls = \"" + selectedCls + "\"");
181                            manager.setSelectedCls(selectedCls);
182                    }
183            }
184    
185            private MouseListener createSelectableListener() {
186                    return new MouseAdapter() {
187    
188                            public void mouseClicked(MouseEvent event) {
189                                    Collection selection = getSelection();
190                                    logger.debug("selection size=" + selection.size());
191                                    if (selection.size() == 1) {
192                                            final Frame selectedFrame = (Frame) selection.iterator().next();
193    
194                                            final TreePath treePath = getPathForLocation(event.getX(), event.getY());
195                                            if (treePath == null) {
196                                                    return;
197                                            }
198                                            boolean addCollapseMenuItem = false;
199                                            if (treePath.getPathCount() == 2) {
200                                                    Object lastComponent = treePath.getLastPathComponent();
201                                                    if (lastComponent instanceof LazyTreeNode) {
202                                                            LazyTreeNode node = (LazyTreeNode) lastComponent;
203                                                            int childCount = node.getChildCount();
204                                                            if (childCount > 0) {
205                                                                    TreeNode childNode = node.getChildAt(0);
206                                                                    TreePath childTreePath = treePath.pathByAddingChild(childNode);
207                                                                    if (!isVisible(childTreePath)) {
208                                                                            expandPath(treePath);
209                                                                            return;
210                                                                    } else
211                                                                            addCollapseMenuItem = true;
212                                                            }
213                                                    }
214                                            }
215    
216                                            popupMenu.removeAll();
217                                            JMenuItem createAnnotationMenuItem = AnnotationSchemaMenuItemFactory.createAnnotationMenuItem(
218                                                            manager, selectedFrame, textSourceUtil);
219                                            if (createAnnotationMenuItem != null) {
220                                                    popupMenu.add(createAnnotationMenuItem);
221                                                    popupMenu.addSeparator();
222                                                    JMenuItem fastAnnotateMenuItem = AnnotationSchemaMenuItemFactory.createFastAnnotateMenuItem(
223                                                                    manager, selectedFrame);
224                                                    popupMenu.add(fastAnnotateMenuItem);
225                                                    if (manager.isFastAnnotateMode() && manager.fastAnnotateToolBarContains(selectedFrame)) {
226                                                            JMenuItem removeItem = AnnotationSchemaMenuItemFactory.createRemoveClsFromToolbarMenuItem(
227                                                                            manager, selectedFrame);
228                                                            popupMenu.add(removeItem);
229                                                    }
230    
231                                            } else {
232                                                    popupMenu.add(new JMenuItem(
233                                                                    "The current filter does not allow creation of annotations of this type."));
234                                            }
235                                            List<JMenuItem> selectAnnotationMenuItems = AnnotationSchemaMenuItemFactory
236                                                            .createSelectAnnotationMenuItems(manager, selectedFrame, AnnotationSchemaTree.this);
237                                            if (selectAnnotationMenuItems != null && selectAnnotationMenuItems.size() > 0)
238                                                    popupMenu.addSeparator();
239                                            for (JMenuItem selectAnnotationMenuItem : selectAnnotationMenuItems) {
240                                                    popupMenu.add(selectAnnotationMenuItem);
241                                            }
242    
243                                            if (addCollapseMenuItem) {
244                                                    popupMenu.addSeparator();
245                                                    JMenuItem menuItem = new JMenuItem("collapse root node");
246                                                    menuItem.addActionListener(new ActionListener() {
247                                                            public void actionPerformed(ActionEvent actionEvent) {
248                                                                    collapsePath(treePath);
249                                                            }
250                                                    });
251                                                    popupMenu.add(menuItem);
252                                            }
253    
254                                            if (popupMenu.getSubElements() != null && popupMenu.getSubElements().length > 0)
255                                                    popupMenu.show(event.getComponent(), event.getX() + 10, event.getY());
256                                    }
257                            }
258                    };
259            }
260    }
261    
262    // final SimpleInstance selectedAnnotation = manager.getSelectedAnnotation();
263    // final Rectangle textBounds = manager.getVisibleTextRect();
264    // popupMenu.addPopupMenuListener(new PopupMenuListener() {
265    // public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
266    //              
267    // }
268    // public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
269    //              
270    // }
271    // public void popupMenuCanceled(PopupMenuEvent e) {
272    // if(manager.getSelectedAnnotation() ==
273    // selectedAnnotation)
274    // manager.setVisibleTextRect(textBounds);
275    // }
276    // });