001 // This file is part of the Attempto Java Packages. 002 // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). 003 // 004 // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the 005 // terms of the GNU Lesser General Public License as published by the Free Software Foundation, 006 // either version 3 of the License, or (at your option) any later version. 007 // 008 // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY 009 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 // PURPOSE. See the GNU Lesser General Public License for more details. 011 // 012 // You should have received a copy of the GNU Lesser General Public License along with the Attempto 013 // Java Packages. If not, see http://www.gnu.org/licenses/. 014 015 package ch.uzh.ifi.attempto.acewiki.gui; 016 017 import java.awt.FontMetrics; 018 import java.awt.Graphics2D; 019 import java.awt.image.BufferedImage; 020 import java.util.ArrayList; 021 022 import nextapp.echo2.app.Alignment; 023 import nextapp.echo2.app.Color; 024 import nextapp.echo2.app.Column; 025 import nextapp.echo2.app.Component; 026 import nextapp.echo2.app.Font; 027 import nextapp.echo2.app.Row; 028 import nextapp.echo2.app.event.ActionEvent; 029 import nextapp.echo2.app.event.ActionListener; 030 import nextapp.echo2.app.layout.RowLayoutData; 031 import ch.uzh.ifi.attempto.acewiki.Wiki; 032 import ch.uzh.ifi.attempto.acewiki.core.ontology.Comment; 033 import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyElement; 034 import ch.uzh.ifi.attempto.acewiki.gui.editor.CommentEditorWindow; 035 import ch.uzh.ifi.attempto.acewiki.gui.editor.SentenceEditorHandler; 036 import ch.uzh.ifi.attempto.acewiki.gui.page.ArticlePage; 037 import ch.uzh.ifi.attempto.acewiki.gui.page.WikiPage; 038 import ch.uzh.ifi.attempto.echocomp.HSpace; 039 import ch.uzh.ifi.attempto.echocomp.MessageWindow; 040 import ch.uzh.ifi.attempto.echocomp.SolidLabel; 041 import ch.uzh.ifi.attempto.echocomp.VSpace; 042 043 /** 044 * This class represents a comment row that consists of a drop down menu and a comment text. 045 * 046 * @author Tobias Kuhn 047 */ 048 public class CommentRow extends Column implements ActionListener { 049 050 private static final long serialVersionUID = -540135972060005725L; 051 052 private static final int COMMENT_TEXT_WIDTH = 800; 053 054 private static FontMetrics fontMetrics = 055 ((Graphics2D) new BufferedImage(2, 2, BufferedImage.TYPE_4BYTE_ABGR_PRE) 056 .createGraphics()).getFontMetrics(new java.awt.Font("Verdana", java.awt.Font.ITALIC, 13)); 057 058 private Comment comment; 059 private Wiki wiki; 060 private WikiPage hostPage; 061 062 private Row commentRow = new Row(); 063 private DropDownMenu dropDown; 064 065 /** 066 * Creates a new comment row. 067 * 068 * @param comment The comment to be shown. 069 * @param hostPage The host page of the comment row. 070 */ 071 public CommentRow(Comment comment, WikiPage hostPage) { 072 this.comment = comment; 073 this.hostPage = hostPage; 074 this.wiki = hostPage.getWiki(); 075 update(); 076 } 077 078 private void update() { 079 dropDown = new DropDownMenu("gray", this); 080 dropDown.addMenuEntry("Edit..."); 081 dropDown.addMenuEntry("Add Sentence..."); 082 dropDown.addMenuEntry("Add Comment..."); 083 dropDown.addMenuEntry("Delete"); 084 RowLayoutData layout = new RowLayoutData(); 085 layout.setAlignment(new Alignment(Alignment.CENTER, Alignment.TOP)); 086 dropDown.setLayoutData(layout); 087 Column c = new Column(); 088 for (String s : (comment.getText() + " ").split("\\n")) { 089 int indent = s.replaceFirst("^(\\s*).*$", "$1").length() * 5; 090 s = s.replaceFirst("^\\s*", ""); 091 if (indent > COMMENT_TEXT_WIDTH/2) indent = COMMENT_TEXT_WIDTH/2; 092 for (Component comp : wrapText(s, COMMENT_TEXT_WIDTH-indent)) { 093 Row r = new Row(); 094 r.add(new VSpace(17)); 095 r.add(new HSpace(indent)); 096 r.add(comp); 097 c.add(r); 098 } 099 } 100 101 removeAll(); 102 commentRow.removeAll(); 103 commentRow.add(dropDown); 104 commentRow.add(new HSpace(5)); 105 commentRow.add(c); 106 commentRow.add(new HSpace(10)); 107 add(commentRow); 108 } 109 110 public void actionPerformed(ActionEvent e) { 111 if (e.getActionCommand().equals("Edit...")) { 112 wiki.log("page", "dropdown: edit comment: " + comment.getText()); 113 wiki.showWindow(new CommentEditorWindow(comment, (ArticlePage) hostPage, true)); 114 } else if (e.getActionCommand().equals("Add Sentence...")) { 115 wiki.log("page", "dropdown: add sentence"); 116 wiki.showWindow(SentenceEditorHandler.generatePreditorAddWindow(comment, (ArticlePage) hostPage)); 117 } else if (e.getActionCommand().equals("Add Comment...")) { 118 wiki.log("page", "dropdown: add comment"); 119 wiki.showWindow(new CommentEditorWindow(comment, (ArticlePage) hostPage, false)); 120 } else if (e.getActionCommand().equals("Delete")) { 121 wiki.log("page", "dropdown: delete sentence: " + comment.getText()); 122 wiki.showWindow(new MessageWindow("Delete", "Do you really want to delete this comment?", null, this, "Yes", "No")); 123 } else if (e.getSource() instanceof MessageWindow && e.getActionCommand().equals("Yes")) { 124 wiki.log("page", "dropdown: delete confirmed: " + comment.getText()); 125 comment.getOwner().remove(comment); 126 wiki.update(); 127 wiki.refresh(); 128 } 129 } 130 131 private ArrayList<Component> wrapText(String text, int width) { 132 ArrayList<Component> wrappedText = new ArrayList<Component>(); 133 String line = ""; 134 Row row = new Row(); 135 text = text.replaceAll("~", "~t").replaceAll(" ", " ~b").replaceAll("\\[\\[", "~b[[").replaceAll("\\]\\]", "]]~b").replaceAll("~t", "~"); 136 for (String s : text.split("~b")) { 137 CommentPart cp = new CommentPart(s); 138 if (line.length() == 0 || fontMetrics.stringWidth(line + cp.getText()) < width) { 139 row.add(cp.getComponent()); 140 line += cp.getText(); 141 if (cp.getText().endsWith(" ")) row.add(new HSpace()); 142 } else { 143 wrappedText.add(row); 144 row = new Row(); 145 row.add(cp.getComponent()); 146 line = cp.getText(); 147 if (cp.getText().endsWith(" ")) row.add(new HSpace()); 148 } 149 } 150 if (line.length() > 0) { 151 wrappedText.add(row); 152 } 153 return wrappedText; 154 } 155 156 157 private class CommentPart extends Component { 158 159 private static final long serialVersionUID = 8522664422692717971L; 160 161 private Component comp; 162 private String text; 163 164 public CommentPart(String s) { 165 if (s.startsWith("http://") || s.startsWith("https://") || s.startsWith("ftp://")) { 166 comp = new WebLink(s); 167 text = s; 168 } else if (s.startsWith("[[") && s.endsWith("]]")) { 169 String name = s.substring(2, s.length()-2); 170 OntologyElement oe = hostPage.getWiki().getOntology().get(name); 171 if (oe != null) { 172 comp = new WikiLink(oe, hostPage.getWiki()); 173 text = name; 174 } 175 } 176 if (comp == null) { 177 SolidLabel label = new SolidLabel(s, Font.ITALIC); 178 label.setForeground(new Color(170, 170, 170)); 179 comp = label; 180 text = s; 181 } 182 } 183 184 public Component getComponent() { 185 return comp; 186 } 187 188 public String getText() { 189 return text; 190 } 191 192 } 193 194 }