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.util.LinkedList;
053:
054: import com.projity.association.InvalidAssociationException;
055: import com.projity.datatype.Duration;
056: import com.projity.field.Field;
057: import com.projity.field.FieldParseException;
058: import com.projity.graphic.configuration.ActionList;
059: import com.projity.graphic.configuration.CellStyle;
060: import com.projity.grouping.core.Node;
061: import com.projity.grouping.core.model.NodeModel;
062: import com.projity.pm.dependency.Dependency;
063: import com.projity.pm.dependency.DependencyService;
064: import com.projity.pm.dependency.DependencyType;
065: import com.projity.pm.graphic.model.cache.NodeModelCache;
066: import com.projity.pm.graphic.spreadsheet.common.CommonSpreadSheetModel;
067: import com.projity.util.ClassUtils;
068: import com.projity.util.Environment;
069:
070: /**
071: *
072: */
073: public class SpreadSheetModel extends CommonSpreadSheetModel {
074: protected boolean readOnly;
075:
076: /**
077: *
078: */
079: public SpreadSheetModel(NodeModelCache cache,
080: SpreadSheetColumnModel colModel, CellStyle cellStyle,
081: ActionList actionList) {
082: super (cache, colModel, cellStyle, actionList);
083: }
084:
085: public int getColumnCount() {
086: return colModel.getFieldColumnCount();
087: }
088:
089: public Field getFieldInColumn(int col) {
090: return SpreadSheetUtils.getFieldInColumn(col, colModel);
091: //return colModel.getFieldInColumn(col);
092: }
093:
094: public Field getFieldInNonTranslatedColumn(int col) {
095: return colModel.getFieldInNonTranslatedColumn(col);
096: }
097:
098: public Object getValueAt(int row, int col) {
099: return SpreadSheetUtils.getValueAt(row, col, getRowMultiple(),
100: cache, colModel, fieldContext);
101: }
102:
103: public String getColumnName(int col) {
104: if (col == 0)
105: return "";
106: return getFieldInColumn(col).getName();
107:
108: }
109:
110: public void setValueAt(Object value, int row, int col) {
111: if (isReadOnly())
112: return;
113: if (col == 0)
114: return;
115: Field field = getFieldInColumn(col);
116: boolean roleField = "Field.userRole".equals(field.getId()); //an exception for roles //TODO get rid of this
117: NodeModel nodeModel = getCache().getModel();
118: if (!nodeModel.isLocal() && !nodeModel.isMaster()
119: && !Environment.getStandAlone() && !roleField)
120: return;
121:
122: // System.out.println("Field " + getFieldInColumn(col) +
123: // "setValueAt("+value+","+row+","+col+")");
124:
125: Object oldValue = getValueAt(row, col);
126: // if (oldValue==null&&(value==null||"".equals(value))) return;
127: if (oldValue == null && ("".equals(value)))
128: return;
129:
130: Node rowNode = getNodeInRow(row);
131: //Field field = getFieldInColumn(col);
132:
133: try {
134: if (rowNode.isVoid()) {
135: if (value == null) { // null means parse error, so generate error here
136: getCache().getModel()
137: .setFieldValue(field, rowNode, this , value,
138: fieldContext, NodeModel.NORMAL);
139: } else {
140: //boolean previousIsParent=false;
141: LinkedList previousNodes = getPreviousVisibleNodesFromRow(row);
142: if (previousNodes != null) {
143: Node nextSibling = getNextNonVoidSiblingFromRow(row);
144: if (nextSibling != null
145: && nextSibling.getParent() == previousNodes
146: .getFirst())
147: previousNodes = null;
148: }
149: getCache().getModel().replaceImplAndSetFieldValue(
150: rowNode, previousNodes,
151: getFieldInColumn(col), this , value,
152: fieldContext, NodeModel.NORMAL);
153:
154: }
155: } else if (rowNode.getImpl() instanceof Dependency) { // dependencies
156: // need
157: // specific
158: // handling
159: // at least
160: // for undo
161: // TODO this code is a hack and does not belong here.
162: Dependency dependency = (Dependency) rowNode.getImpl();
163: DependencyService dependencyService = DependencyService
164: .getInstance();
165: try {
166: Duration duration = (Duration) ((col == 4) ? value
167: : getValueAt(row, 4)); // TODO
168: // can
169: // not
170: // assume
171: // column
172: // positions
173: int type = ((Number) DependencyType
174: .mapStringToValue((String) ((col == 3) ? value
175: : getValueAt(row, 3)))).intValue();
176:
177: dependencyService.setFields(dependency, duration
178: .getEncodedMillis(), type, this );
179: dependencyService.update(dependency, this );
180: } catch (InvalidAssociationException e1) {
181: // TODO Auto-generated catch block
182: e1.printStackTrace();
183: }
184: } else {
185: getCache().getModel().setFieldValue(field, rowNode,
186: this , value, fieldContext, NodeModel.NORMAL);
187: }
188: } catch (FieldParseException e) {
189: throw new RuntimeException(e); // exceptions will be treated by the spreadsheet, not the model, because there is a popup. Because this method doesn't have an exception, a runtime exception will be caught by the spreadsheet
190: }
191: }
192:
193: public boolean isRowEditable(int row) {
194: if (isReadOnly())
195: return false;
196: NodeModel nodeModel = getCache().getModel();
197: //if (!nodeModel.isLocal()&&!nodeModel.isMaster()&&!Environment.getStandAlone()) return false;
198: Node node = getNodeInRow(row);
199: if (node.isVoid())
200: return true;
201: return !ClassUtils.isObjectReadOnly(node.getImpl());
202: }
203:
204: public boolean isCellEditable(int row, int col) {
205: if (isReadOnly())
206: return false;
207: if (col == 0)
208: return false;
209: Field field = getFieldInColumn(col);
210: if (field.getLookupTypes() != null)
211: return false;
212: Node node = getNodeInRow(row);
213: NodeModel nodeModel = getCache().getModel();
214: // if (!nodeModel.isLocal()&&!nodeModel.isMaster()&&!Environment.getStandAlone()) return false;
215:
216: if (node.isVoid()
217: && !(nodeModel.isLocal() || nodeModel.isMaster())
218: && "Field.userRole".equals(field.getId()))
219: return false;
220:
221: if (node.isVoid())
222: return true;
223: return !field.isReadOnly(node, getCache().getWalkersModel(),
224: null);
225: }
226:
227: private int findFieldColumn(Field field) {
228: return colModel.findFieldColumn(field);
229: }
230:
231: public boolean isReadOnly() {
232: return readOnly;
233: }
234:
235: public void setReadOnly(boolean readOnly) {
236: this.readOnly = readOnly;
237: }
238:
239: }
|