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;
051:
052: import java.awt.Dimension;
053: import java.util.Collection;
054: import java.util.List;
055:
056: import javax.swing.JScrollPane;
057: import javax.swing.event.ChangeEvent;
058: import javax.swing.event.ChangeListener;
059:
060: import com.projity.configuration.Dictionary;
061: import com.projity.configuration.FieldDictionary;
062: import com.projity.field.Field;
063: import com.projity.field.FieldContext;
064: import com.projity.graphic.configuration.SpreadSheetCategories;
065: import com.projity.graphic.configuration.SpreadSheetFieldArray;
066: import com.projity.grouping.core.Node;
067: import com.projity.grouping.core.model.NodeModel;
068: import com.projity.grouping.core.model.NodeModelDataFactory;
069: import com.projity.grouping.core.model.NodeModelFactory;
070: import com.projity.grouping.core.transform.ViewTransformer;
071: import com.projity.grouping.core.transform.filtering.BelongsToCollectionFilter;
072: import com.projity.grouping.core.transform.filtering.NodeFilter;
073: import com.projity.pm.graphic.frames.DocumentFrame;
074: import com.projity.pm.graphic.model.cache.GraphicNode;
075: import com.projity.pm.graphic.model.cache.NodeModelCache;
076: import com.projity.pm.graphic.model.cache.NodeModelCacheFactory;
077: import com.projity.pm.graphic.model.cache.ReferenceNodeModelCache;
078: import com.projity.pm.graphic.model.transform.NodeCacheTransformer;
079: import com.projity.pm.graphic.views.UsageDetailView;
080: import com.projity.strings.Messages;
081:
082: /**
083: * Helper methods for working with spreadsheets
084: */
085:
086: public class SpreadSheetUtils {
087:
088: public static void setFieldsAndContext(SpreadSheet ss,
089: NodeModelCache cache, String spreadSheetCategory,
090: String spreadSheetId, boolean leftAssociation) {
091: SpreadSheetFieldArray fields = (SpreadSheetFieldArray) Dictionary
092: .get(spreadSheetCategory, Messages
093: .getString(spreadSheetId));
094: ss.setCache(cache, fields, fields.getCellStyle(), fields
095: .getActionList());
096: FieldContext fieldContext = new FieldContext();
097: fieldContext.setLeftAssociation(leftAssociation);
098: ((SpreadSheetModel) ss.getModel())
099: .setFieldContext(fieldContext);
100: ((SpreadSheetModel) ss.getModel()).getCache().update();
101: }
102:
103: /** Refresh the contents of a collection based spreadsheet
104: * @param ss
105: * @param collection
106: * @param document
107: * @param viewId
108: * @param spreadSheetCategory
109: * @param spreadSheetId
110: * @param leftAssociation
111: * @param nbVoidNodes TODO
112: */
113: public static void createCollectionSpreadSheet(
114: SpreadSheet ss,
115: Collection collection
116: //,Document document
117: , String viewId, String spreadSheetCategory,
118: String spreadSheetId, boolean leftAssociation,
119: NodeModelDataFactory dataFactory, int nbVoidNodes
120: // ,boolean local
121: // ,boolean master
122: ) {
123: NodeModel nodeModel = NodeModelFactory.getInstance()
124: .createNodeModelFromCollection(collection, dataFactory);
125: // nodeModel.setLocal(local);
126: // nodeModel.setMaster(master);
127: nodeModel.getHierarchy().setNbEndVoidNodes(nbVoidNodes);
128: ReferenceNodeModelCache refCache = NodeModelCacheFactory
129: .getInstance().createReferenceCache(
130: nodeModel, /*document*/
131: null,
132: ((leftAssociation) ? NodeModelCache.TASK_TYPE
133: : NodeModelCache.RESOURCE_TYPE)
134: | NodeModelCache.ASSIGNMENT_TYPE);
135: NodeModelCache cache = NodeModelCacheFactory.getInstance()
136: .createFilteredCache(refCache,
137: Messages.getString(viewId), null);
138: setFieldsAndContext(ss, cache, spreadSheetCategory,
139: spreadSheetId, leftAssociation);
140:
141: }
142:
143: public static void updateCollectionSpreadSheet(SpreadSheet ss,
144: Collection collection, NodeModelDataFactory dataFactory,
145: int nbVoidNodes) {
146:
147: ss.clearActions();
148: NodeModel nodeModel = ss.getCache().getModel();
149: NodeModelFactory.getInstance().updateNodeModelFromCollection(
150: nodeModel, collection, dataFactory, nbVoidNodes);
151: }
152:
153: /**
154: * This one doesn't recreate the cache and all its associated objects since they allready exist in the main referenceNodeModelCache.
155: * It just applies a filter. (a simplified version of SelectionFilter used by UsageDetail)
156: * @param nbVoidNodes TODO
157: * @param popupActions TODO
158: */
159: public static SpreadSheet createFilteredSpreadsheet(
160: DocumentFrame df,
161: boolean task // if task based
162: , String viewId, String spreadSheetCategory,
163: String spreadSheetId, boolean leftAssociation
164: //,int nbVoidNodes
165: , String[] actionList) {
166:
167: NodeModelCache cache = df.createCache(task, Messages
168: .getString(viewId));
169: cache.update();
170: return createFilteredSpreadsheet(cache, spreadSheetCategory,
171: spreadSheetId, leftAssociation,/*nbVoidNodes,*/
172: actionList);
173: }
174:
175: public static SpreadSheet createFilteredSpreadsheet(
176: NodeModelCache cache, String spreadSheetCategory,
177: String spreadSheetId, boolean leftAssociation
178: //,int nbVoidNodes
179: , String[] actionList) {
180: SpreadSheet ss = new SpreadSheet();
181: ss
182: .setSpreadSheetCategory(leftAssociation ? UsageDetailView.taskAssignmentSpreadsheetCategory
183: : UsageDetailView.resourceAssignmentSpreadsheetCategory);
184: //cache.getModel().getHierarchy().setNbEndVoidNodes(nbVoidNodes);
185: setFieldsAndContext(ss, cache, spreadSheetCategory,
186: spreadSheetId, leftAssociation);
187: return ss;
188: }
189:
190: /**
191: * changes filter's collection
192: */
193: public static void updateFilteredSpreadsheet(SpreadSheet ss,
194: Collection collection) {
195: ViewTransformer transformer = ((NodeCacheTransformer) ss
196: .getCache().getVisibleNodes().getTransformer())
197: .getTransformer();
198: NodeFilter filter = transformer.getHiddenFilter();
199: if (filter instanceof BelongsToCollectionFilter)
200: ((BelongsToCollectionFilter) filter).setSelectedNodesImpl(
201: collection, true);
202: }
203:
204: /** put a spreadsheet in a scroll pane and fix problems with scrolling header
205: *
206: * @param spreadSheet
207: * @return
208: */
209: public static JScrollPane makeSpreadsheetScrollPane(
210: SpreadSheet spreadSheet) {
211: final JScrollPane spreadSheetScrollPane = new JScrollPane(
212: spreadSheet);
213: //a fix to resize column header when viewport size changes
214: spreadSheetScrollPane.getViewport().addChangeListener(
215: new ChangeListener() {
216: private Dimension olddmain = null;
217:
218: public void stateChanged(ChangeEvent e) {
219: // Dimension dmain=spreadSheetScrollPane.getViewport().getViewSize();
220: // if (dmain.equals(olddmain)) return;
221: // olddmain=dmain;
222: // System.out.println("pref size #1="+spreadSheetScrollPane.getColumnHeader().getPreferredSize());
223: // spreadSheetScrollPane.getColumnHeader().setPreferredSize(new Dimension(dmain.width,spreadSheetScrollPane.getColumnHeader().getPreferredSize().height));
224: // System.out.println("pref size #2="+spreadSheetScrollPane.getColumnHeader().getPreferredSize());
225: // spreadSheetScrollPane.getColumnHeader().revalidate();
226: // System.out.println("pref size #3="+spreadSheetScrollPane.getColumnHeader().getPreferredSize());
227: //
228:
229: // Dimension d=spreadSheetScrollPane.getColumnHeader().getPreferredSize();
230: // d.setSize(dmain.getWidth(),d.getHeight());
231: // spreadSheetScrollPane.getColumnHeader().revalidate();
232: }
233: });
234: return spreadSheetScrollPane;
235: }
236:
237: public static List getFieldsForCategory(String category) {
238: if (category
239: .equals(SpreadSheetCategories.projectSpreadsheetCategory)) {
240: return FieldDictionary.getInstance().getProjectFields();
241: } else if (category
242: .equals(SpreadSheetCategories.taskSpreadsheetCategory)) {
243: return FieldDictionary.getInstance().getTaskFields();
244: } else if (category
245: .equals(SpreadSheetCategories.resourceSpreadsheetCategory)) {
246: return FieldDictionary.getInstance().getResourceFields();
247: } else if (category
248: .equals(SpreadSheetCategories.taskAssignmentSpreadsheetCategory)
249: || category
250: .equals(SpreadSheetCategories.resourceAssignmentSpreadsheetCategory)) {
251: return FieldDictionary.getInstance().getAssignmentFields();
252: } else if (category
253: .equals(SpreadSheetCategories.dependencySpreadsheetCategory)) {
254: return FieldDictionary.getInstance().getDependencyFields();
255: }
256: //TODO resource usage should use resource and assignment fields, and task usage should do task and assignment fields
257:
258: return null;
259:
260: }
261:
262: public static GraphicNode getNodeFromCacheRow(int row,
263: int rowMultiple, NodeModelCache cache) {
264: return (GraphicNode) cache.getElementAt(row / rowMultiple);
265: }
266:
267: public static Node getNodeInRow(int row, int rowMultiple,
268: NodeModelCache cache) {
269: GraphicNode gnode = getNodeFromCacheRow(row, rowMultiple, cache);
270: if (gnode == null)
271: return null;
272: return gnode.getNode();
273:
274: }
275:
276: public static Field getFieldInColumn(int col,
277: SpreadSheetColumnModel colModel) {
278: return colModel.getFieldInColumn(col);
279: }
280:
281: public static Object getValueAt(int row, int col, int rowMultiple,
282: NodeModelCache cache, SpreadSheetColumnModel colModel,
283: FieldContext context) {
284: Node node = getNodeInRow(row, rowMultiple, cache);
285: return getValueAt(node, col, cache, colModel, context);
286: }
287:
288: public static Object getValueAt(Node node, int col,
289: NodeModelCache cache, SpreadSheetColumnModel colModel,
290: FieldContext context) {
291: if (node.isVoid())
292: return (col == 0) ? "" : null;
293: // TODO change when Field supports void
294: return getFieldInColumn(col, colModel).getValue(node,
295: cache.getWalkersModel(), context);
296: }
297:
298: }
|