001: /**
002: * Copyright 2004 Carlos Silva A.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */package com.csa.lgantt.view.adapters;
017:
018: import java.awt.Color;
019: import java.awt.Dimension;
020: import java.awt.Graphics;
021: import java.awt.image.BufferedImage;
022: import java.io.File;
023: import java.io.FileOutputStream;
024: import java.io.IOException;
025: import java.util.Date;
026:
027: import sun.awt.image.codec.JPEGParam;
028:
029: import com.csa.lgantt.model.Change;
030: import com.csa.lgantt.model.ChangeSupport;
031: import com.csa.lgantt.model.Project;
032: import com.csa.lgantt.model.Task;
033: import com.csa.lgantt.model.ViewOptions;
034: import com.csa.lgantt.view.GanttActionListener;
035: import com.csa.lgantt.view.gantt.GanttGraph;
036: import com.csa.lgantt.view.tree.TaskTree;
037: import com.sun.image.codec.jpeg.ImageFormatException;
038: import com.sun.image.codec.jpeg.JPEGCodec;
039: import com.sun.image.codec.jpeg.JPEGEncodeParam;
040: import com.sun.image.codec.jpeg.JPEGImageEncoder;
041:
042: /**
043: * ProjectViewModel representa el estado de visualizacion del proyecto Ademas
044: * provee la ejeucion de funciones de soporte a la interfaz como movimientos de
045: * tareas, creacion, borrado etc.
046: *
047: * TODO: Documentar mas
048: *
049: * <p>
050: * $Date: 2006/10/10 02:47:57 $
051: * </p>
052: *
053: * @version $Revision: 1.2 $
054: * @author Carlos Silva
055: */
056: public class ProjectViewModel {
057: Project project;
058:
059: GanttActionListener mainActionListener;
060:
061: Task currentTask = null;
062:
063: File file = null;
064:
065: Date currentSnapShot = null;
066:
067: public Date getCurrentSnapShot() {
068: return currentSnapShot;
069: }
070:
071: public void setCurrentSnapShot(Date d) {
072: currentSnapShot = d;
073: viewOptions.notifyObservers();
074: }
075:
076: ViewOptions viewOptions = null;
077:
078: public ProjectViewModel(Project p, File f) {
079: setProject(p, f);
080: setCurrentTask(null);
081: mainActionListener = new GanttActionListener(this );
082: }
083:
084: /**
085: * Asigna un nuevo proyecto, TODO: asigna los observadores del proyecto
086: * antiguo al proyecto nuevo. notifica del nuevo proyecto cargado.
087: *
088: * @param p
089: * @param f
090: */
091: public void setProject(Project p, File f) {
092: project = p;
093: file = f;
094: setCurrentTask(null);
095: viewOptions = p.getViewOptions();
096:
097: sendChange(new ProjectViewModelChange(
098: ProjectViewModelChange.NEW_PROJECT_LOADED, this ));
099: }
100:
101: /**
102: * Asigna el archivo de trabajo.
103: *
104: * @param f
105: */
106: public void setFile(File f) {
107: file = f;
108: }
109:
110: /**
111: * Retorna el archivo de trabajo actual
112: *
113: * @return
114: */
115: public File getFile() {
116: return file;
117: }
118:
119: public Project getProject() {
120: return project;
121: }
122:
123: public ViewOptions getViewOptions() {
124: return viewOptions;
125: }
126:
127: public Task getCurrentTask() {
128: return currentTask;
129: }
130:
131: public void setCurrentTask(Task newTask) {
132: Task oldTask = currentTask;
133: currentTask = newTask;
134: if (oldTask == newTask)
135: return;
136: sendChange(new ProjectViewModelChange(
137: ProjectViewModelChange.CURRENT_TASK_CHANGED, this ,
138: currentTask));
139: }
140:
141: public GanttActionListener getMainActionListener() {
142: return mainActionListener;
143: }
144:
145: /**
146: * Observer, observadores de esta clase
147: *
148: * <p>
149: * $Date: 2006/10/10 02:47:57 $
150: * </p>
151: *
152: * @version $Revision: 1.2 $
153: * @author {user}
154: */
155: public static interface Observer {
156: public void newProjectLoaded(ProjectViewModel pvm);
157:
158: public void currentTaskChanged(Task currentTask, Task oldTask);
159: }
160:
161: /**
162: * hace que esta tarea sea la ultima hija de su hermana anterior
163: */
164: public void asChildTask() {
165: if (currentTask == null)
166: return;
167: currentTask.asChild();
168: }
169:
170: /**
171: * Hace que esta tarea sea la ultima hija de su hermana anterior
172: */
173: public void deChildTask() {
174: if (currentTask == null)
175: return;
176: currentTask.deChild();
177: }
178:
179: /**
180: * Hace que esta tarea sea la ultima hija de su hermana anterior
181: */
182: public void goUpTask() {
183:
184: if (currentTask == null)
185: return;
186: currentTask.goUp();
187: }
188:
189: /**
190: * Hace que esta tarea sea la ultima hija de su hermana anterior
191: */
192: public void goDownTask() {
193:
194: if (currentTask == null)
195: return;
196: currentTask.goDown();
197: }
198:
199: /**
200: * Inserta una tarea vacia en el projecto antes de la tarea actual
201: */
202: public void insertTask() {
203: // System.out.println("TaskTree2.insertTask() focusTask="+focusTask);
204: Task newTask = project.createTask("");
205: if (currentTask != null)
206: currentTask.addBefore(newTask);
207: else
208: project.getMainTask().addChild(newTask);
209: setCurrentTask(newTask);
210: }
211:
212: /**
213: * Inserta una tarea vacia en el projecto
214: */
215: public void appendTask() {
216: // System.out.println("TaskTree2.insertTask() focusTask="+focusTask);
217: Task newTask = project.createTask("");
218: if (currentTask != null)
219: currentTask.addAfter(newTask);
220: else
221: project.getMainTask().addChild(newTask);
222: setCurrentTask(newTask);
223: }
224:
225: /**
226: * Borra la tarea actual en la pantalla
227: */
228: public void deleteCurrentTask() {
229: if (currentTask != null) {
230: int id = currentTask.getId();
231: currentTask.remove();
232: if (project.getTaskCount() == 0)
233: setCurrentTask(null);
234: else if (id >= project.getTaskCount())
235: setCurrentTask(project
236: .getTask(project.getTaskCount() - 1));
237: else if (id > 0)
238: setCurrentTask(project.getTask(id - 1));
239: else
240: setCurrentTask(null);
241: }
242: }
243:
244: GanttGraph ganttGraph = null;
245:
246: public void setGanttGraph(GanttGraph gg) {
247: ganttGraph = gg;
248: }
249:
250: TaskTree taskTree = null;
251:
252: public void setTaskTree(TaskTree tt) {
253: taskTree = tt;
254: }
255:
256: /**
257: * Graba una imagen de la carta gantt segun las opciones existentes.
258: *
259: * @param f
260: * @throws ImageFormatException
261: * @throws IOException
262: */
263: public void exportImage(File f) throws ImageFormatException,
264: IOException {
265: BufferedImage image = makeImage();
266: FileOutputStream out = new FileOutputStream(f);
267: JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
268: //encoder.encode(image);
269:
270: JPEGEncodeParam params = encoder
271: .getDefaultJPEGEncodeParam(image);
272: params.setQuality(1f, true);
273: encoder.encode(image, params);
274:
275: out.flush();
276: out.close();
277: }
278:
279: /**
280: * Genera una imagen de la carta gantt con las condiciones existentes
281: *
282: * @return
283: */
284: public BufferedImage makeImage() {
285: Dimension treeSize = taskTree.getImageSize();
286: Dimension graphSize = ganttGraph.getImageSize();
287:
288: // Crear imagen en memoria
289: int imWidth = treeSize.width + graphSize.width;
290: BufferedImage preview = new BufferedImage(imWidth,
291: treeSize.height, BufferedImage.TYPE_INT_RGB);
292: Graphics g = preview.getGraphics();
293:
294: int topRow = getViewOptions().getTopRow();
295: getViewOptions().setTopRow(0);
296:
297: int leftPos = taskTree.getLeftPos();
298: taskTree.setLeftPos(0);
299:
300: // Escribir la imagen en g.
301: taskTree.paintTree(g);
302:
303: // mover el punto 0
304: g.translate(treeSize.width, 0);
305: ganttGraph.paintGraph(g);
306:
307: g.dispose();
308: g = preview.getGraphics();
309:
310: g.setColor(Color.black);
311: g.drawRect(0, 0, imWidth - 1, treeSize.height - 1);
312:
313: g.dispose();
314: getViewOptions().setTopRow(topRow);
315: taskTree.setLeftPos(leftPos);
316: return preview;
317: }
318:
319: // Soporte a eventos
320: /**
321: * Objeto para administrar listeners
322: */
323: protected ChangeSupport changeSupport = new ChangeSupport() {
324: protected void notifyListener(Object listener, Change change) {
325: ((ProjectViewModelListener) listener)
326: .viewModelChanged((ProjectViewModelChange) change);
327: }
328: };
329:
330: /**
331: * Agrega un listener a los suscritos
332: *
333: * @param o
334: */
335: public void addListener(ProjectViewModelListener listener) {
336: changeSupport.addListener(listener);
337: }
338:
339: /**
340: * Remueve un listener de los suscritos
341: *
342: * @param listener
343: */
344: public void removeListener(ProjectViewModelListener listener) {
345: changeSupport.removeListener(listener);
346: }
347:
348: /**
349: * Comienza una bloque de cambios que deben despacharse todos juntos al
350: * final.
351: * <p>
352: * El ultimo mensaje del bloque se envia con la marca:<code>isLast</code>.
353: * </p>
354: */
355: public void beginBlockChanges() {
356: changeSupport.beginBlockChanges();
357: }
358:
359: /**
360: * Envia en bloque todos los cambios recibidos y que estan en la cola.
361: * <p>
362: * El ultimo mensaje del bloque se envia con la marca:<code>isLast</code>.
363: * </p>
364: */
365: public void commitBlockChanges() {
366: changeSupport.commitBlockChanges();
367: }
368:
369: /**
370: * Envia una cambio a todos los escuchadores
371: *
372: * @param change
373: * ProjectChange
374: */
375: public void sendChange(ProjectViewModelChange change) {
376: changeSupport.sendChange(change);
377: }
378:
379: }
|