001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.pm.graphic.spreadsheet.common.transfer;
051:
052: import java.awt.datatransfer.DataFlavor;
053: import java.awt.datatransfer.Transferable;
054: import java.awt.datatransfer.UnsupportedFlavorException;
055: import java.io.IOException;
056: import java.io.StringReader;
057: import java.util.ArrayList;
058: import java.util.Date;
059: import java.util.HashSet;
060: import java.util.Iterator;
061: import java.util.List;
062: import java.util.Set;
063: import java.util.StringTokenizer;
064:
065: import org.apache.commons.collections.CollectionUtils;
066:
067: import com.projity.field.Field;
068: import com.projity.field.FieldContext;
069: import com.projity.field.FieldParseException;
070: import com.projity.grouping.core.Node;
071: import com.projity.grouping.core.NodeFactory;
072: import com.projity.grouping.core.model.NodeModel;
073: import com.projity.grouping.core.model.NodeModelDataFactory;
074: import com.projity.options.EditOption;
075: import com.projity.pm.graphic.spreadsheet.SpreadSheet;
076: import com.projity.pm.graphic.spreadsheet.common.CommonSpreadSheetModel;
077: import com.projity.pm.resource.ResourcePool;
078: import com.projity.pm.task.Project;
079: import com.projity.pm.task.Task;
080:
081: /**
082: *
083: */
084: public class NodeListTransferable implements Transferable {
085: private static final int NODE_LIST = 0;
086: private static final int STRING = 1;
087: private static final int PLAIN_TEXT = 2;
088:
089: public static final String NODE_LIST_MIME_TYPE = DataFlavor.javaJVMLocalObjectMimeType
090: + ";class=java.util.ArrayList";
091:
092: private DataFlavor[] flavors;
093: private DataFlavor nodeListDataFlavor;
094: private Set flavorSet;
095:
096: protected ArrayList nodeList;
097: protected ArrayList fields;
098: protected SpreadSheet spreadsheet;
099: protected int[] rows, cols;
100: protected boolean nodeSelection;
101:
102: //protected String sdata;
103:
104: public NodeListTransferable(ArrayList nodeList, ArrayList fields,
105: SpreadSheet spreadSheet, int[] rows, int[] cols,
106: boolean nodeSelection) {
107: this .nodeSelection = nodeSelection;
108: try {
109: nodeListDataFlavor = new DataFlavor(NODE_LIST_MIME_TYPE);
110: } catch (ClassNotFoundException e) {
111: }
112: if (nodeSelection) {
113: flavors = new DataFlavor[] { nodeListDataFlavor,
114: DataFlavor.stringFlavor,
115: DataFlavor.getTextPlainUnicodeFlavor() }; //TODO isRepresentationClassReader(||InputStream)||isFlavorTextType+flavor.getReaderForText()
116: this .nodeList = nodeList;
117: this .fields = fields;
118: } else {
119: flavors = new DataFlavor[] { DataFlavor.stringFlavor,
120: DataFlavor.getTextPlainUnicodeFlavor() }; //TODO isRepresentationClassReader(||InputStream)||isFlavorTextType+flavor.getReaderForText()
121: //sdata=nodeListToString(nodeList,spreadSheet,fields);
122: }
123: flavorSet = new HashSet();
124: //Collections.addAll(flavorSet,flavors); //jdk 1.5
125: //for (int i=0;i<flavors.length;i++) flavorSet.add(flavors[i]);
126: CollectionUtils.addAll(flavorSet, flavors); //replaced JDK 1.5 code with this call
127: this .spreadsheet = spreadSheet;
128: this .rows = rows;
129: this .cols = cols;
130: }
131:
132: public DataFlavor[] getTransferDataFlavors() {
133: return (DataFlavor[]) flavors.clone();
134: }
135:
136: public boolean isDataFlavorSupported(DataFlavor flavor) {
137: for (int i = 0; i < flavors.length; i++) {
138: if (flavor.equals(flavors[i])) {
139: return true;
140: }
141: }
142: return false;
143: }
144:
145: public Object getTransferData(DataFlavor flavor)
146: throws UnsupportedFlavorException, IOException {
147: if (!flavorSet.contains(flavor))
148: throw new UnsupportedFlavorException(flavor);
149: if (nodeListDataFlavor.equals(flavor)) {
150: NodeModel model = ((CommonSpreadSheetModel) spreadsheet
151: .getModel()).getCache().getModel();
152: // ArrayList nl=nodeList;
153: // nodeList=new ArrayList(nl.size());
154: // nodeList.addAll(model.copy(nl,NodeModel.SILENT));
155: return model.copy(nodeList, NodeModel.SILENT);
156: } else if (DataFlavor.stringFlavor.equals(flavor))
157: return selectionToString(spreadsheet, rows, cols);
158: // return (sdata==null)?nodeListToString(nodeList,spreadsheet,fields):sdata;
159: else if (DataFlavor.getTextPlainUnicodeFlavor().equals(flavor))
160: return new StringReader(selectionToString(spreadsheet,
161: rows, cols));
162: //return new StringReader((sdata==null)?nodeListToString(nodeList,spreadsheet,fields):sdata);
163: else
164: throw new UnsupportedFlavorException(flavor);
165: }
166:
167: // public Object getTransferData(DataFlavor[] flavors) throws UnsupportedFlavorException, IOException {
168: // for (int i=0;i<flavors.length;i++){
169: // if (isDataFlavorSupported(flavors[i]))
170: // return getTransferData(flavors[i]);
171: // }
172: // throw new UnsupportedFlavorException(flavors[0]);
173: //}
174:
175: public static String nodeListToString(List nodeList,
176: SpreadSheet spreadsheet, List fields) {
177: StringBuffer sb = new StringBuffer();
178: for (Iterator i = nodeList.iterator(); i.hasNext();) {
179: nodeToString((Node) i.next(), sb, spreadsheet, fields);
180: }
181: return sb.toString();
182: }
183:
184: public static void nodeToString(Node node, StringBuffer sb,
185: SpreadSheet spreadsheet, List fields) {
186: CommonSpreadSheetModel model = (CommonSpreadSheetModel) spreadsheet
187: .getModel();
188: Object value;
189: Field field;
190: Iterator fieldsIterator = fields.iterator();
191: boolean first = true;
192: //String s=null;
193: while (fieldsIterator.hasNext()) {
194: field = (Field) fieldsIterator.next();
195: value = field.getValue(node, model.getCache()
196: .getWalkersModel(), model.getFieldContext());
197: if (first)
198: first = false;
199: else
200: sb.append('\t');
201: sb.append((value == null) ? "" : value.toString());
202: //s=sb.toString();
203: //System.out.println("s="+s);
204: }
205: sb.append('\n');
206: for (Iterator i = node.childrenIterator(); i.hasNext();)
207: nodeToString((Node) i.next(), sb, spreadsheet, fields);
208: }
209:
210: public static String selectionToString(SpreadSheet spreadsheet,
211: int[] rows, int[] cols) {
212: StringBuffer sb = new StringBuffer();
213: Object value;
214: for (int r = 0; r < rows.length; r++) {
215: for (int c = 0; c < cols.length; c++) {
216: value = spreadsheet.getValueAt(rows[r], cols[c]);
217: if (value != null && !(value instanceof Task))
218: if (value instanceof Date)
219: sb.append(EditOption.getInstance()
220: .getDateFormat().format((Date) value));
221: else
222: sb.append(value.toString());
223: if (c < cols.length - 1)
224: sb.append('\t');
225: else
226: sb.append('\n');
227: }
228: }
229: return sb.toString();
230: }
231:
232: public static ArrayList stringToNodeList(String s,
233: SpreadSheet spreadsheet, List fields,
234: NodeModelDataFactory factory) {
235: ArrayList list = new ArrayList();
236: StringTokenizer st = new StringTokenizer(s, "\n\r");
237: Node node;
238: while (st.hasMoreTokens()) {
239: node = stringToNode(st.nextToken(), spreadsheet, fields,
240: factory);
241: if (node != null)
242: list.add(node);
243: }
244: return list;
245: }
246:
247: public static Node stringToNode(String s, SpreadSheet spreadsheet,
248: List fields, NodeModelDataFactory factory) {
249: String category = spreadsheet.getSpreadSheetCategory();
250: Node node = null;
251: String delim = "\t";
252: StringTokenizer st = new StringTokenizer(s, delim, true);
253: if (st.hasMoreTokens()) {
254: if (SpreadSheet.TASK_CATEGORY.equals(category))
255: node = NodeFactory.getInstance().createTask(
256: (Project) factory);
257: else if (SpreadSheet.RESOURCE_CATEGORY.equals(category))
258: node = NodeFactory.getInstance().createResource(
259: (ResourcePool) factory);
260: else
261: return null;
262:
263: CommonSpreadSheetModel model = (CommonSpreadSheetModel) spreadsheet
264: .getModel();
265: String valueS;
266: Field field;
267: Iterator fieldsIterator = fields.iterator();
268: while (st.hasMoreTokens() && fieldsIterator.hasNext()) {
269: valueS = st.nextToken();
270: if (delim.equals(valueS))
271: valueS = "";
272: else if (st.hasMoreTokens())
273: st.nextToken();
274: field = (Field) fieldsIterator.next();
275: try {
276: field.setValue(node, model.getCache()
277: .getWalkersModel(), spreadsheet, valueS,
278: model.getFieldContext());
279: } catch (FieldParseException e) {
280: }
281: }
282: }
283: return node;
284: }
285:
286: public static void pasteString(String s, SpreadSheet spreadsheet) {
287: int[] rows = spreadsheet.getSelectedRows();
288: int[] cols = spreadsheet.getSelectedColumns();
289: if (rows.length > 0 && cols.length > 0)
290: pasteString(s, spreadsheet, rows[0], cols[0]);
291: }
292:
293: public static void pasteString(String s, SpreadSheet spreadsheet,
294: int row0, int col0) {
295: StringTokenizer st = new StringTokenizer(s, "\n");
296: int row = row0;//,maxRow=spreadsheet.getRowCount()-1;
297: while (st.hasMoreTokens()/*&&row<=maxRow*/)
298: //maxRow useless, maxRow increased automatically
299: pasteStringLine(st.nextToken(), spreadsheet, row++, col0);
300: }
301:
302: public static void pasteStringLine(String s,
303: SpreadSheet spreadsheet, int row0, int col0) {
304: String valueS;
305: CommonSpreadSheetModel model = (CommonSpreadSheetModel) spreadsheet
306: .getModel();
307: String delim = "\t";
308: StringTokenizer st = new StringTokenizer(s, delim, true);
309: int col = col0, maxCol = spreadsheet.getColumnCount() - 1;
310: FieldContext fieldContext = model.getFieldContext();
311: boolean round = fieldContext.isRound();
312: fieldContext.setRound(true);
313: while (st.hasMoreTokens() && col <= maxCol) {
314: valueS = st.nextToken();
315: if (delim.equals(valueS))
316: valueS = "";
317: else if (st.hasMoreTokens())
318: st.nextToken();
319: try {
320: model.setValueAt(valueS, row0, ++col);
321: } catch (Exception e) {
322: }
323: }
324: fieldContext.setRound(round);
325: }
326:
327: // public boolean isNodeSelection() {
328: // return nodeSelection;
329: // }
330: //
331: // public ArrayList getSelectedFields(){
332: // return (nodeSelection)?spreadsheet.getSelectableFields():spreadsheet.getSelectedFields();
333: // }
334:
335: }
|