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.dialog;
051:
052: import java.awt.Dimension;
053: import java.awt.Frame;
054: import java.util.LinkedList;
055:
056: import javax.swing.JButton;
057: import javax.swing.JComponent;
058: import javax.swing.JLabel;
059: import javax.swing.JScrollPane;
060: import javax.swing.JTabbedPane;
061:
062: import com.jgoodies.forms.builder.DefaultFormBuilder;
063: import com.jgoodies.forms.layout.CellConstraints;
064: import com.jgoodies.forms.layout.FormLayout;
065: import com.projity.association.AssociationList;
066: import com.projity.configuration.Settings;
067: import com.projity.dialog.util.FieldComponentMap;
068: import com.projity.grouping.core.model.NodeModel;
069: import com.projity.help.HelpUtil;
070: import com.projity.menu.MenuActionConstants;
071: import com.projity.pm.costing.CostRateTable;
072: import com.projity.pm.graphic.frames.DocumentFrame;
073: import com.projity.pm.graphic.frames.DocumentSelectedEvent;
074: import com.projity.pm.graphic.frames.GraphicManager;
075: import com.projity.pm.graphic.model.cache.NodeModelCache;
076: import com.projity.pm.graphic.spreadsheet.SpreadSheet;
077: import com.projity.pm.graphic.spreadsheet.SpreadSheetModel;
078: import com.projity.pm.graphic.spreadsheet.SpreadSheetUtils;
079: import com.projity.pm.graphic.views.UsageDetailView;
080: import com.projity.pm.resource.Resource;
081: import com.projity.pm.resource.ResourceImpl;
082: import com.projity.strings.Messages;
083:
084: /**
085: *
086: */
087: public class ResourceInformationDialog extends InformationDialog {
088: private static final long serialVersionUID = 1L;
089:
090: public static ResourceInformationDialog getInstance(Frame owner,
091: Resource resource) {
092: return new ResourceInformationDialog(owner, resource);
093: }
094:
095: private ResourceInformationDialog(Frame owner, Resource resource) {
096: super (
097: owner,
098: Messages
099: .getString("ResourceInformationDialog.ResourceInformation")); //$NON-NLS-1$
100: setObjectClass(Resource.class);
101: setObject(resource);
102: addDocHelp("Resource_Information_Dialog");
103: }
104:
105: private JTabbedPane resourceTabbedPane;
106: private int notesTabIndex;
107: private JLabel availabilityLabel;
108: private JButton changeWorkingTimeButton;
109:
110: public JComponent createContentPanel() {
111: FormLayout layout = new FormLayout(
112: "400dlu:grow", "fill:275dlu:grow"); //$NON-NLS-1$ //$NON-NLS-2$
113: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
114: builder.setDefaultDialogBorder();
115: resourceTabbedPane = new JTabbedPane();
116: JComponent generalTab = createGeneralPanel();
117: JComponent costsTab = createCostsPanel();
118: resourceTabbedPane
119: .addTab(
120: Messages
121: .getString("ResourceInformationDialog.General"), generalTab); //$NON-NLS-1$
122: resourceTabbedPane
123: .addTab(
124: Messages
125: .getString("ResourceInformationDialog.Costs"), costsTab); //$NON-NLS-1$
126: resourceTabbedPane
127: .addTab(
128: Messages
129: .getString("ResourceInformationDialog.Tasks"), createTasksPanel()); //$NON-NLS-1$
130: String notes = Messages
131: .getString("ResourceInformationDialog.Notes"); //$NON-NLS-1$
132: resourceTabbedPane.addTab(notes, createNotesPanel());
133: notesTabIndex = resourceTabbedPane.indexOfTab(notes);
134:
135: builder.add(resourceTabbedPane);
136: mainComponent = resourceTabbedPane;
137: return builder.getPanel();
138: }
139:
140: public void showNotes() {
141: resourceTabbedPane.setSelectedIndex(notesTabIndex);
142:
143: }
144:
145: public JComponent createGeneralPanel() {
146: FieldComponentMap map = createMap();
147:
148: FormLayout layout = new FormLayout(
149: "p, 3dlu, 160dlu, 3dlu, p, 3dlu, p, 3dlu", //$NON-NLS-1$
150: "p,3dlu,p,3dlu,p,3dlu,p,3dlu,p,0dlu,p,3dlu,p,3dlu, fill:50dlu:grow"); //$NON-NLS-1$
151:
152: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
153: builder.setDefaultDialogBorder();
154: CellConstraints cc = new CellConstraints();
155: map.append(builder, "Field.name"); //$NON-NLS-1$
156: map.append(builder, "Field.initials"); //$NON-NLS-1$
157: builder.nextLine(2);
158: map.append(builder, "Field.emailAddress"); //$NON-NLS-1$
159: map.append(builder, "Field.group"); //$NON-NLS-1$
160: builder.nextLine(2);
161: map.append(builder, "Field.rbsCode"); //$NON-NLS-1$
162: map.append(builder, "Field.resourceType"); //$NON-NLS-1$
163: builder.nextLine(2);
164: map.append(builder, "Field.bookingType"); //$NON-NLS-1$
165: map.appendSometimesReadOnly(builder, "Field.materialLabel"); //$NON-NLS-1$
166: builder.nextLine(2);
167: builder.addLabel(map.getLabel("Field.baseCalendar") + ":"); //$NON-NLS-1$ //$NON-NLS-2$
168: builder.nextColumn(2);
169: changeWorkingTimeButton = getChangeWorkingTimeButton();
170: builder.append(pairedComponents(map,
171: "Field.baseCalendar", 0, changeWorkingTimeButton)); //$NON-NLS-1$
172: builder.nextColumn(2);
173: map.append(builder, "Field.generic"); //$NON-NLS-1$
174: builder.nextLine(2);
175: builder.nextColumn(6);
176: map.append(builder, "Field.inactive"); //$NON-NLS-1$
177: builder.nextLine(2);
178: availabilityLabel = builder
179: .addLabel(Messages
180: .getString("ResourceInformationDialog.ResourceAvailability")); //$NON-NLS-1$
181: builder.nextLine(2);
182:
183: builder.add(createAvailabilitySpreadsheet(), cc.xyw(builder
184: .getColumn(), builder.getRow(), 4));
185: return builder.getPanel();
186:
187: }
188:
189: public JComponent createTasksPanel() {
190: FieldComponentMap map = createMap();
191:
192: FormLayout layout = new FormLayout(
193: "p:grow", "p,3dlu,p,3dlu,fill:150dlu:grow"); //$NON-NLS-1$ //$NON-NLS-2$
194:
195: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
196: builder.setDefaultDialogBorder();
197: CellConstraints cc = new CellConstraints();
198: builder.add(createHeaderFieldsPanel(map), cc.xyw(builder
199: .getColumn(), builder.getRow(), 1));
200: builder.nextLine(2);
201: builder
202: .append(Messages
203: .getString("ResourceInformationDialog.AssignedToTasks")); // not using assigned button //$NON-NLS-1$
204: builder.nextLine(2);
205: builder.add(createAssignmentSpreadsheet(), cc.xyw(builder
206: .getColumn(), builder.getRow(), 1));
207: JComponent panel = builder.getPanel();
208: HelpUtil.addDocHelp(panel, "Assign_Resources");
209:
210: return panel;
211: }
212:
213: protected SpreadSheet assignmentSpreadSheet;
214: private JScrollPane assignmentPane;
215:
216: protected JScrollPane createAssignmentSpreadsheet() {
217: assignmentSpreadSheet = SpreadSheetUtils
218: .createFilteredSpreadsheet(
219: GraphicManager.getInstance(this )
220: .getCurrentFrame(),
221: true,
222: "View.ResourceInformation.Assignments" //$NON-NLS-1$
223: ,
224: UsageDetailView.taskAssignmentSpreadsheetCategory,
225: "Spreadsheet.Assignment.taskUsage" //$NON-NLS-1$
226: ,
227: false
228: //, 0
229: ,
230: new String[] { MenuActionConstants.ACTION_DELETE }/*,new int[] {SpreadSheet.DELETE}*/);
231: assignmentSpreadSheet.setCanModifyColumns(true);
232: assignmentSpreadSheet.setCanSelectFieldArray(true);
233: assignmentSpreadSheet
234: .setActions(new String[] { MenuActionConstants.ACTION_DELETE });
235:
236: updateAssignmentSpreadsheet();
237: assignmentPane = SpreadSheetUtils
238: .makeSpreadsheetScrollPane(assignmentSpreadSheet);
239: return assignmentPane;
240: }
241:
242: protected void updateAssignmentSpreadsheet() {
243: SpreadSheetUtils.updateFilteredSpreadsheet(
244: assignmentSpreadSheet,
245: (object == null) ? new AssociationList()
246: : ((Resource) object).getAssignments());
247: }
248:
249: private SpreadSheet availabilitySpreadsheet;
250: JScrollPane availabilityPane;
251:
252: protected JScrollPane createAvailabilitySpreadsheet() {
253: availabilitySpreadsheet = new SpreadSheet() {
254: protected void doPostExceptionTreatment() { // this is a bit of a hack.
255: updateAvailabilitySpreadsheet();
256: requestFocus();
257: }
258:
259: };
260:
261: availabilitySpreadsheet
262: .setSpreadSheetCategory("availabilitySpreadsheet"); //$NON-NLS-1$
263: availabilitySpreadsheet.setCanSelectFieldArray(false);
264: //availabilitySpreadsheet.setActions(new String[]{SpreadSheet.DELETE});
265:
266: // availabilitySpreadsheet.setHasRowPopup(false);
267: ResourceImpl resourceImpl = (ResourceImpl) object;
268: SpreadSheetUtils.createCollectionSpreadSheet(
269: availabilitySpreadsheet,
270: (object == null) ? new LinkedList() : resourceImpl
271: .getAvailabilityTable().getList()
272: //,(object==null)?null:((Resource)object).getDocument()
273: , "View.ResourceInformation.Availability" //$NON-NLS-1$
274: , "availabilitySpreadsheet" //$NON-NLS-1$
275: , "Spreadsheet.availability" //$NON-NLS-1$
276: , false, (object == null) ? null
277: : ((ResourceImpl) object)
278: .getAvailabilityTable(), 1
279: // ,resourceImpl.getGlobalResource().isLocal()
280: // ,resourceImpl.getGlobalResource().isMaster()
281: );
282: availabilityPane = SpreadSheetUtils
283: .makeSpreadsheetScrollPane(availabilitySpreadsheet);
284: return availabilityPane;
285: }
286:
287: protected void updateAvailabilitySpreadsheet() {
288: SpreadSheetUtils.updateCollectionSpreadSheet(
289: availabilitySpreadsheet,
290: (object == null) ? new LinkedList()
291: : ((ResourceImpl) object)
292: .getAvailabilityTable().getList(),
293: (object == null) ? null : ((ResourceImpl) object)
294: .getAvailabilityTable(), 1);
295: if (object != null) {
296: ResourceImpl resourceImpl = (ResourceImpl) object;
297: NodeModel model = ((SpreadSheetModel) availabilitySpreadsheet
298: .getModel()).getCache().getModel();
299: // availabilitySpreadsheet.clearActions();
300: availabilitySpreadsheet.setReadOnly(resourceImpl
301: .isReadOnly());
302: model
303: .setMaster(resourceImpl.getGlobalResource()
304: .isMaster());
305: model.setLocal(resourceImpl.getGlobalResource().isLocal());
306: //TODO instead of doing this availabilityTable and Availability can contain a read-only field
307: }
308:
309: }
310:
311: private SpreadSheet costTableSpreadsheets[] = new SpreadSheet[Settings.NUM_COST_RATES];
312:
313: protected SpreadSheet createCostTableSpreadsheet(
314: CostRateTable costRateTable) {
315: SpreadSheet ss = new SpreadSheet() {
316: protected void doPostExceptionTreatment() {
317: updateCostTableSpreadsheets();
318: requestFocus();
319: }
320:
321: };
322: //ss.setActions(new String[]{SpreadSheet.DELETE});
323:
324: ss.setSpreadSheetCategory("costRates"); //$NON-NLS-1$
325: ss.setCanSelectFieldArray(false);
326: // ss.setHasRowPopup(false);
327:
328: return ss;
329:
330: }
331:
332: protected void createCostTableSpreadsheets() {
333: ResourceImpl resourceImpl = (ResourceImpl) object;
334: for (int i = 0; i < Settings.NUM_COST_RATES; i++) {
335: SpreadSheetUtils.createCollectionSpreadSheet(
336: costTableSpreadsheets[i],
337: (object == null) ? new LinkedList() : resourceImpl
338: .getCostRateTable(i).getList()
339: //,(object==null)?null:((Resource)object).getDocument()
340: ,
341: "View.ResourceInformation.CostRate" //$NON-NLS-1$
342: ,
343: "costRates" //$NON-NLS-1$
344: ,
345: "Spreadsheet.costRates" //$NON-NLS-1$
346: , false, (object == null) ? null
347: : ((Resource) object).getCostRateTable(i),
348: 1
349: // ,resourceImpl.getGlobalResource().isLocal()
350: // ,resourceImpl.getGlobalResource().isMaster()
351: );
352: }
353: }
354:
355: protected void updateCostTableSpreadsheets() {
356: for (int i = 0; i < Settings.NUM_COST_RATES; i++) {
357: SpreadSheetUtils.updateCollectionSpreadSheet(
358: costTableSpreadsheets[i],
359: (object == null) ? new LinkedList()
360: : ((Resource) object).getCostRateTable(i)
361: .getList(), (object == null) ? null
362: : ((Resource) object).getCostRateTable(i),
363: 1);
364: if (object != null) {
365: ResourceImpl resourceImpl = (ResourceImpl) object;
366: NodeModel model = ((SpreadSheetModel) costTableSpreadsheets[i]
367: .getModel()).getCache().getModel();
368: // costTableSpreadsheets[i].clearActions();
369: costTableSpreadsheets[i].setReadOnly(resourceImpl
370: .isReadOnly());
371: model.setMaster(resourceImpl.getGlobalResource()
372: .isMaster());
373: model.setLocal(resourceImpl.getGlobalResource()
374: .isLocal());
375: //TODO instead of doing this availabilityTable and Availability can contain a read-only field
376: }
377: }
378: }
379:
380: JTabbedPane costTabbedPane;
381:
382: public JComponent createCostsPanel() {
383: FieldComponentMap map = createMap();
384: FormLayout layout = new FormLayout(
385: "50dlu,3dlu,50dlu,3dlu,p:grow", //$NON-NLS-1$
386: "p,3dlu,p,3dlu,fill:p:grow,3dlu,p,3dlu,p"); //$NON-NLS-1$
387:
388: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
389: builder.setDefaultDialogBorder();
390: CellConstraints cc = new CellConstraints();
391: builder.add(createHeaderFieldsPanel(map), cc.xyw(builder
392: .getColumn(), builder.getRow(), 3));
393:
394: costTabbedPane = new JTabbedPane();
395: CostRateTable costRateTable;
396: for (int i = 0; i < 5; i++) {
397: costRateTable = ((Resource) object).getCostRateTable(i);
398: costTableSpreadsheets[i] = createCostTableSpreadsheet(costRateTable);
399: costTableSpreadsheets[i]
400: .setPreferredScrollableViewportSize(new Dimension(
401: 500, 200));
402: JScrollPane ssPane = SpreadSheet
403: .createScrollPaneForTable(costTableSpreadsheets[i]);
404: costTabbedPane.addTab(costRateTable.getName(), ssPane);
405: }
406: createCostTableSpreadsheets();
407: builder.nextLine(2);
408: builder.addSeparator(Messages.getString("Text.CostRateTables")); //$NON-NLS-1$
409: builder.nextLine(2);
410: builder.add(costTabbedPane, cc.xyw(builder.getColumn(), builder
411: .getRow(), 5));
412: builder.nextLine(2);
413: map.append(builder, "Field.accrueAt"); //$NON-NLS-1$
414: return builder.getPanel();
415:
416: }
417:
418: /* (non-Javadoc)
419: * @see com.projity.dialog.InformationDialog#createHeaderFieldsPanel(com.projity.dialog.util.FieldComponentMap)
420: */
421: protected JComponent createHeaderFieldsPanel(FieldComponentMap map) {
422: FormLayout layout = new FormLayout("p, 3dlu, 160dlu", //$NON-NLS-1$
423: "p"); //$NON-NLS-1$
424: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
425: map.append(builder, "Field.name"); //$NON-NLS-1$
426: return builder.getPanel();
427: }
428:
429: protected void setVisibleAndEnabledState() {
430: super .setVisibleAndEnabledState();
431: boolean showing = (object != null && object instanceof Resource);
432: assignmentPane.setVisible(showing);
433: costTabbedPane.setVisible(showing);
434: boolean isLaborResource = showing
435: && ((Resource) object).isLabor();
436: availabilityPane.setVisible(isLaborResource);
437: availabilityLabel.setEnabled(isLaborResource);
438: }
439:
440: public void updateAll() {
441: activateListeners();
442: super .updateAll();
443: updateAssignmentSpreadsheet();
444: updateCostTableSpreadsheets();
445: updateAvailabilitySpreadsheet();
446: changeWorkingTimeButton.setEnabled(getObject() != null
447: && !((ResourceImpl) getObject()).isReadOnly());
448:
449: }
450:
451: public void documentSelected(DocumentSelectedEvent evt) {
452: if (assignmentSpreadSheet == null)
453: return;
454: DocumentFrame df = evt.getCurrent();
455: if (df != null) {
456: NodeModelCache cache = df.createCache(true, Messages
457: .getString("View.TaskInformation.Assignments")); //$NON-NLS-1$
458: assignmentSpreadSheet.setCache(cache);
459: }
460: }
461:
462: protected void activateListeners() {
463: super .activateListeners();
464: for (int i = 0; i < costTableSpreadsheets.length; i++)
465: costTableSpreadsheets[i].getCache().setReceiveEvents(true);
466: availabilitySpreadsheet.getCache().setReceiveEvents(true);
467: //assignmentSpreadSheet.getCache().setReceiveEvents(true);
468: }
469:
470: protected void desactivateListeners() {
471: super .desactivateListeners();
472: for (int i = 0; i < costTableSpreadsheets.length; i++)
473: costTableSpreadsheets[i].getCache().setReceiveEvents(true);
474: availabilitySpreadsheet.getCache().setReceiveEvents(false);
475: //assignmentSpreadSheet.getCache().setReceiveEvents(false);
476: //causes an update problem of the filtered cache
477: }
478:
479: }
|