001: package net.sourceforge.squirrel_sql.fw.gui.action;
002:
003: /*
004: * Copyright (C) 2001-2004 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: import java.awt.Toolkit;
022: import java.awt.datatransfer.Clipboard;
023: import java.awt.datatransfer.DataFlavor;
024: import java.awt.datatransfer.Transferable;
025: import java.awt.datatransfer.UnsupportedFlavorException;
026: import java.io.ByteArrayInputStream;
027: import java.io.IOException;
028:
029: import javax.swing.JTable;
030: import javax.swing.table.TableCellRenderer;
031:
032: import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.SquirrelTableCellRenderer;
033: import net.sourceforge.squirrel_sql.fw.util.ICommand;
034: import net.sourceforge.squirrel_sql.fw.util.StringManager;
035: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
036: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
037: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
038:
039: /**
040: * This command gets the current selected text from a <TT>JTable</TT>
041: * and formats it as HTML table and places it on the system clipboard.
042: *
043: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
044: */
045: public class TableCopyHtmlCommand implements ICommand {
046: /** The table we are copying data from. */
047: private JTable _table;
048:
049: private static HTMLSelection htmlSelection = null;
050:
051: private static final StringManager s_stringMgr = StringManagerFactory
052: .getStringManager(TableCopyHtmlCommand.class);
053:
054: /** Logger for this class. */
055: private static ILogger s_log = LoggerController
056: .createLogger(TableCopyHtmlCommand.class);
057:
058: /**
059: * Ctor specifying the <TT>JTable</TT> to get the data from.
060: *
061: * @param table The <TT>JTable</TT> to get data from.
062: *
063: * @throws IllegalArgumentException
064: * Thrown if <tt>null</tt> <tt>JTable</tt> passed.
065: */
066: public TableCopyHtmlCommand(JTable table) {
067: super ();
068: if (table == null) {
069: throw new IllegalArgumentException("JTable == null");
070: }
071: _table = table;
072: if (htmlSelection == null) {
073: try {
074: htmlSelection = new HTMLSelection();
075: } catch (Exception e) {
076: String msg = s_stringMgr
077: .getString("TableCopyHtmlCommand.error.flavors");
078: s_log.error(msg, e);
079: }
080: }
081: }
082:
083: /**
084: * Execute this command.
085: */
086: public void execute() {
087: int nbrSelRows = _table.getSelectedRowCount();
088: int nbrSelCols = _table.getSelectedColumnCount();
089: int[] selRows = _table.getSelectedRows();
090: int[] selCols = _table.getSelectedColumns();
091:
092: if (selRows.length != 0 && selCols.length != 0) {
093: StringBuffer buf = new StringBuffer(1024);
094: buf.append("<table border=1><tr BGCOLOR=\"#CCCCFF\">");
095: for (int colIdx = 0; colIdx < nbrSelCols; ++colIdx) {
096: buf.append("<th>");
097: buf.append(_table.getColumnName(selCols[colIdx]));
098: buf.append("</th>");
099: }
100: buf.append("</tr>\n");
101: for (int rowIdx = 0; rowIdx < nbrSelRows; ++rowIdx) {
102: buf.append("<tr>");
103: for (int colIdx = 0; colIdx < nbrSelCols; ++colIdx) {
104: TableCellRenderer cellRenderer = _table
105: .getCellRenderer(selRows[rowIdx],
106: selCols[colIdx]);
107: Object cellObj = _table.getValueAt(selRows[rowIdx],
108: selCols[colIdx]);
109:
110: if (cellRenderer instanceof SquirrelTableCellRenderer) {
111: cellObj = ((SquirrelTableCellRenderer) cellRenderer)
112: .renderValue(cellObj);
113: }
114:
115: buf.append("<td>");
116: if (cellObj == null) {
117: buf.append(" ");
118: } else {
119: final String tmp = cellObj.toString();
120: if (tmp.trim().equals("")) {
121: buf.append(" ");
122: } else {
123: buf.append(htmlizeString(tmp));
124: }
125: }
126: // else if (cellObj instanceof String)
127: // {
128: // final String tmp = (String)cellObj;
129: // if (tmp.trim().equals(""))
130: // buf.append(" ");
131: // else
132: // {
133: // buf.append(htmlizeString(tmp));
134: // }
135: // }
136: // else
137: // {
138: // buf.append(cellObj);
139: // }
140: buf.append("</td>");
141: }
142: buf.append("</tr>\n");
143: }
144: buf.append("</table>");
145:
146: htmlSelection.setData(buf.toString());
147: Clipboard cb = Toolkit.getDefaultToolkit()
148: .getSystemClipboard();
149: cb.setContents(htmlSelection, null);
150: }
151: }
152:
153: private static final String htmlizeString(String str) {
154: final StringBuffer buf = new StringBuffer(1024);
155: for (int i = 0, limit = str.length(); i < limit; ++i) {
156: switch (str.charAt(i)) {
157: case '<':
158: buf.append("<");
159: break;
160: case '>':
161: buf.append(">");
162: break;
163: case '&':
164: buf.append("&");
165: break;
166: case '"':
167: buf.append(""");
168: break;
169: case '\n':
170: buf.append("<BR>");
171: break;
172: default:
173: buf.append(str.charAt(i));
174: }
175: }
176: return buf.toString();
177: }
178:
179: /**
180: * A custom transferable that will inform the system clipboard that the
181: * data being transferred "prefers" to be represented in HTML format /
182: * MIME type is "text/html". Will fallback to "text/plain" for applications
183: * that don't support "text/html".
184: */
185: private static class HTMLSelection implements Transferable {
186:
187: DataFlavor[] supportedFlavors = null;
188: String _data = null;
189:
190: /**
191: * Constructor.
192: *
193: * @throws Exception if the "html" or "plain" flavors cannot be resolved.
194: */
195: public HTMLSelection() throws Exception {
196: DataFlavor htmlFlavor = new DataFlavor("text/html");
197: DataFlavor plainFlavor = new DataFlavor("text/plain");
198: supportedFlavors = new DataFlavor[] { htmlFlavor,
199: plainFlavor };
200: }
201:
202: /**
203: * Sets the data that will be transferred to the clipboard.
204: *
205: * @param data the data to transfer.
206: */
207: public void setData(String data) {
208: _data = data;
209: }
210:
211: /* (non-Javadoc)
212: * @see java.awt.datatransfer.Transferable#getTransferDataFlavors()
213: */
214: public DataFlavor[] getTransferDataFlavors() {
215: return supportedFlavors;
216: }
217:
218: /* (non-Javadoc)
219: * @see java.awt.datatransfer.Transferable#isDataFlavorSupported(java.awt.datatransfer.DataFlavor)
220: */
221: public boolean isDataFlavorSupported(DataFlavor flavor) {
222: boolean result = false;
223: for (int i = 0; i < supportedFlavors.length; i++) {
224: DataFlavor f = supportedFlavors[i];
225: if (f.getMimeType().equals(flavor.getMimeType())) {
226: result = true;
227: }
228: }
229: return result;
230: }
231:
232: /* (non-Javadoc)
233: * @see java.awt.datatransfer.Transferable#getTransferData(java.awt.datatransfer.DataFlavor)
234: */
235: public Object getTransferData(DataFlavor flavor)
236: throws UnsupportedFlavorException, IOException {
237: if (isDataFlavorSupported(flavor)) {
238: return new ByteArrayInputStream(_data.getBytes());
239: } else {
240: throw new UnsupportedFlavorException(flavor);
241: }
242: }
243:
244: }
245: }
|