1 /*
2 * Created on 04.03.2004
3 */
4 package org.xpcards;
5
6 import java.beans.XMLDecoder;
7 import java.io.File;
8 import java.io.FileInputStream;
9 import java.io.FileNotFoundException;
10 import java.io.FileOutputStream;
11 import java.text.MessageFormat;
12 import java.util.Enumeration;
13 import java.util.Hashtable;
14 import java.util.MissingResourceException;
15 import java.util.ResourceBundle;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.custom.CTabFolder;
19 import org.eclipse.swt.custom.SashForm;
20 import org.eclipse.swt.custom.TableTreeItem;
21 import org.eclipse.swt.events.SelectionEvent;
22 import org.eclipse.swt.events.SelectionListener;
23 import org.eclipse.swt.layout.FillLayout;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.swt.widgets.Display;
26 import org.eclipse.swt.widgets.Event;
27 import org.eclipse.swt.widgets.Listener;
28 import org.eclipse.swt.widgets.Menu;
29 import org.eclipse.swt.widgets.MenuItem;
30 import org.eclipse.swt.widgets.Shell;
31 import org.xpcards.actions.AbstractAction;
32 import org.xpcards.actions.EditStory;
33 import org.xpcards.actions.NewIteration;
34 import org.xpcards.actions.NewProject;
35 import org.xpcards.actions.NewStory;
36 import org.xpcards.actions.NewTask;
37 import org.xpcards.actions.Open;
38 import org.xpcards.actions.Save;
39 import org.xpcards.actions.SaveAs;
40 import org.xpcards.model.IModelElementListener;
41 import org.xpcards.model.ModelElement;
42 import org.xpcards.model.ModelElementCollection;
43 import org.xpcards.model.Project;
44 import org.xpcards.model.ProjectSource;
45 import org.xpcards.model.ProjectsCollection;
46 import org.xpcards.model.XPEncoder;
47
48 /***
49 * @author Mikhail Galyutin
50 */
51 public class XPCards {
52
53 private static ResourceBundle resourceBundle = ResourceBundle.getBundle("xpcards");
54 private static String DEFAULT_PROJECTS_COLLECTION = "projects.xpc";
55
56 private Hashtable actionMap = null;
57
58 private SashForm verticalSplit = null;
59 private SashForm horizontalSplit = null;
60 private CTabFolder tabFolder = null;
61 private PlanningTab planningTab = null;
62 private ProjectsTreeView projectsTreeView = null;
63
64 private boolean isModified = false;
65
66 private ModelElement currentElement = null;
67 private ProjectsCollection projects = null;
68 private File projectCollectionFile = null;
69
70 // private File file = null;
71 private Shell shell = null;
72
73 public AbstractAction getAction(String key) {
74 if (actionMap == null) {
75 return null;
76 } else {
77 return (AbstractAction) actionMap.get(key);
78 }
79 }
80
81 public void putAction(String key, AbstractAction action) {
82 if (actionMap == null) {
83 actionMap = new Hashtable();
84 }
85 actionMap.put(key, action);
86 }
87
88 private void initActions() {
89 putAction(EditStory.ACTION_ID, new EditStory());
90 // putAction(Save.ACTION_ID, new Save());
91
92 putAction(NewIteration.ACTION_ID, new NewIteration());
93 putAction(NewProject.ACTION_ID, new NewProject());
94 putAction(NewStory.ACTION_ID, new NewStory());
95 putAction(NewTask.ACTION_ID, new NewTask());
96 // putAction(Open.ACTION_ID, new Open());
97 // putAction(Save.ACTION_ID, new Save());
98 // putAction(SaveAs.ACTION_ID, new SaveAs());
99 }
100
101 private IModelElementListener modelListener = new IModelElementListener() {
102
103 /* (non-Javadoc)
104 * @see org.xpcards.model.IModelElementListener#propertyChanged(org.xpcards.model.ModelElement, java.lang.String, java.lang.Object, java.lang.Object)
105 */
106 public void propertyChanged(ModelElement source, String propertyName, Object oldValue, Object newValue) {
107 // System.err.println("collectionElementChanged:" + source + "," + oldValue + "," + newValue);
108 if (planningTab != null) {
109 setModified(true);
110 planningTab.updateModelElement(source);
111 }
112 }
113
114 /* (non-Javadoc)
115 * @see org.xpcards.model.IModelElementListener#collectionElementAdded(org.xpcards.model.ModelElement, org.xpcards.model.ModelElement, java.lang.String)
116 */
117 public void collectionElementAdded(
118 ModelElement element,
119 ModelElement parent,
120 String collectionName,
121 boolean recursive) {
122 // System.err.println("collectionElementAdded:" + element + "," + parent + "," + collectionName);
123 setModified(true);
124 updatePlanningTab(element, parent, collectionName, recursive);
125 }
126
127 /* (non-Javadoc)
128 * @see org.xpcards.model.IModelElementListener#collectionElementRemoved(org.xpcards.model.ModelElement, org.xpcards.model.ModelElement, java.lang.String)
129 */
130 public void collectionElementRemoved(ModelElement element, ModelElement parent, String collectionName) {
131 // System.err.println("collectionElementRemoved:" + element + "," + parent + "," + collectionName);
132
133 if (planningTab != null) {
134 setModified(true);
135 planningTab.removeModelElement(element);
136 }
137 }
138
139 };
140
141 private final SelectionListener treeSelectionListener = new SelectionListener() {
142 public void widgetDefaultSelected(SelectionEvent e) {
143 // System.err.println("widgetDefaultSelected:" + e);
144 // System.err.println("detail:" + e.detail);
145 // System.err.println("height:" + e.height);
146 // System.err.println("stateMask:" + e.stateMask);
147 // System.err.println("time:" + e.time);
148 // System.err.println("width:" + e.width);
149 // System.err.println("item:" + e.item);
150 // System.err.println("widjet:" + e.widget);
151 // System.err.println("doit:" + e.doit);
152 // System.err.println("data:" + e.data);
153 //
154
155 widgetSelected(e);
156 }
157 public void widgetSelected(SelectionEvent e) {
158
159 // System.err.println("widgetSelected:" + e);
160 // System.err.println("detail:" + e.detail);
161 // System.err.println("height:" + e.height);
162 // System.err.println("stateMask:" + e.stateMask);
163 // System.err.println("time:" + e.time);
164 // System.err.println("width:" + e.width);
165 // System.err.println("item:" + e.item);
166 // System.err.println("widjet:" + e.widget);
167 // System.err.println("doit:" + e.doit);
168 // System.err.println("data:" + e.data);
169
170 if (planningTab != null) {
171 ModelElement el = planningTab.getModelElementByTableTreeItem((TableTreeItem) e.item);
172 if (el != null) {
173 selectModelElement(el);
174 }
175 }
176
177 }
178
179 };
180
181 /***
182 *
183 */
184 public XPCards(Shell parent) {
185 shell = parent;
186 initActions();
187 initResources();
188 initProjectCollection();
189
190 shell.setLayout(new FillLayout());
191 verticalSplit = new SashForm(parent, SWT.HORIZONTAL);
192 verticalSplit.setLayout(new FillLayout());
193
194 // CTabFolder vstf = new CTabFolder(verticalSplit, SWT.BOTTOM);
195 // CTabItem pvi = new CTabItem(vstf, SWT.NONE);
196
197 projectsTreeView = new ProjectsTreeView(this, verticalSplit);
198 // pvi.setText(projectsTreeView.getName());
199 // pvi.setControl(projectsTreeView.getControl());
200
201 horizontalSplit = new SashForm(verticalSplit, SWT.VERTICAL);
202 horizontalSplit.setLayout(new FillLayout());
203
204 tabFolder = new CTabFolder(horizontalSplit, SWT.NONE);
205
206 createPlanningTab(tabFolder);
207
208 // TODO Create TaskView
209 Composite c1 = new Composite(horizontalSplit, SWT.BORDER);
210
211 createMenu(parent.getShell());
212
213 // TODO Sash form weights
214 horizontalSplit.setWeights(new int[] { 80, 20 });
215 verticalSplit.setWeights(new int[] { 30, 70 });
216
217 }
218
219 private void createPlanningTab(CTabFolder parent) {
220 planningTab = new PlanningTab(this, parent);
221 planningTab.addTreeSelectionListener(treeSelectionListener);
222 planningTab.setText(getResourceString("Tab.Planning.Text"));
223
224 }
225
226 private void createFileMenu(final Menu bar, final Shell shell) {
227 MenuItem item = new MenuItem(bar, SWT.CASCADE);
228 item.setText(XPCards.getResourceString("Menu.File"));
229 shell.setMenuBar(bar);
230 Menu dropDown = new Menu(bar);
231 item.setMenu(dropDown);
232
233 final MenuItem open = new MenuItem(dropDown, SWT.NONE);
234 open.setText(XPCards.getResourceString("Menu.File.Open"));
235 open.addListener(SWT.Selection, new Listener() {
236 public void handleEvent(Event e) {
237 getAction(Open.ACTION_ID).performAction(shell, XPCards.this, null);
238 }
239 });
240
241 final MenuItem save = new MenuItem(dropDown, SWT.NONE);
242 save.setText(XPCards.getResourceString("Menu.File.Save"));
243 save.addListener(SWT.Selection, new Listener() {
244 public void handleEvent(Event e) {
245 getAction(Save.ACTION_ID).performAction(shell, XPCards.this, null);
246 }
247 });
248
249 final MenuItem saveAs = new MenuItem(dropDown, SWT.NONE);
250 saveAs.setText(XPCards.getResourceString("Menu.File.SaveAs"));
251 saveAs.addListener(SWT.Selection, new Listener() {
252 public void handleEvent(Event e) {
253 getAction(SaveAs.ACTION_ID).performAction(shell, XPCards.this, null);
254 }
255 });
256
257 final MenuItem exit = new MenuItem(dropDown, SWT.NONE);
258 exit.setText(XPCards.getResourceString("Menu.File.Exit"));
259 exit.addListener(SWT.Selection, new Listener() {
260 public void handleEvent(Event e) {
261 shell.dispose();
262 }
263 });
264
265 }
266
267 private void createProjectsMenu(final Menu bar, final Shell shell) {
268 MenuItem item = new MenuItem(bar, SWT.CASCADE);
269 item.setText(XPCards.getResourceString("Menu.Projects"));
270 shell.setMenuBar(bar);
271 Menu dropDown = new Menu(bar);
272 item.setMenu(dropDown);
273
274 final MenuItem newProject = new MenuItem(dropDown, SWT.NONE);
275 newProject.setText(XPCards.getResourceString("Menu.Projects.NewProject"));
276 newProject.addListener(SWT.Selection, new Listener() {
277 public void handleEvent(Event e) {
278 // TODO Action map delegate perform
279 getAction(NewProject.ACTION_ID).performAction(shell, XPCards.this, null);
280 }
281 });
282
283 final MenuItem newStory = new MenuItem(dropDown, SWT.NONE);
284 newStory.setText(XPCards.getResourceString("Menu.Projects.NewStory"));
285 newStory.addListener(SWT.Selection, new Listener() {
286 public void handleEvent(Event e) {
287 // TODO Action map delegate perform
288 getAction(NewStory.ACTION_ID).performAction(shell, XPCards.this, null);
289 }
290 });
291
292 final MenuItem editStory = new MenuItem(dropDown, SWT.NONE);
293 editStory.setText(XPCards.getResourceString("Menu.Projects.NewStory"));
294 editStory.addListener(SWT.Selection, new Listener() {
295 public void handleEvent(Event e) {
296 // TODO Action map delegate perform
297 getAction(EditStory.ACTION_ID).performAction(shell, XPCards.this, null);
298 }
299 });
300
301 final MenuItem newIteration = new MenuItem(dropDown, SWT.NONE);
302 newIteration.setText(XPCards.getResourceString("Menu.Projects.NewIteration"));
303 newIteration.addListener(SWT.Selection, new Listener() {
304 public void handleEvent(Event e) {
305 // TODO Action map delegate perform
306 getAction(NewIteration.ACTION_ID).performAction(shell, XPCards.this, null);
307 }
308 });
309
310 final MenuItem newTask = new MenuItem(dropDown, SWT.NONE);
311 newTask.setText(XPCards.getResourceString("Menu.Projects.NewTask"));
312 newTask.addListener(SWT.Selection, new Listener() {
313 public void handleEvent(Event e) {
314 // TODO Action map delegate perform
315 getAction(NewTask.ACTION_ID).performAction(shell, XPCards.this, null);
316 }
317 });
318
319 }
320
321 /***
322 * Create the menubar
323 */
324 void createMenu(final Shell shell) {
325 Menu bar = new Menu(shell, SWT.BAR);
326 createFileMenu(bar, shell);
327 createProjectsMenu(bar, shell);
328 }
329
330 /***
331 * Gets a string from the resource bundle.
332 * We don't want to crash because of a missing String.
333 * Returns the key if not found.
334 */
335 static String getResourceString(String key) {
336 try {
337 return resourceBundle.getString(key);
338 } catch (MissingResourceException e) {
339 return key;
340 } catch (NullPointerException e) {
341 return "!" + key + "!";
342 }
343 }
344
345 /***
346 * Gets a string from the resource bundle and binds it
347 * with the given arguments. If the key is not found,
348 * return the key.
349 */
350 static String getResourceString(String key, Object[] args) {
351 try {
352 return MessageFormat.format(getResourceString(key), args);
353 } catch (MissingResourceException e) {
354 return key;
355 } catch (NullPointerException e) {
356 return "!" + key + "!";
357 }
358 }
359
360 /***
361 * Loads the resources
362 */
363 void initResources() {
364 final Class clazz = XPCards.class;
365 if (resourceBundle != null) {
366 try {
367 // if (images == null) {
368 // images = new Image[imageLocations.length];
369 //
370 // for (int i = 0; i < imageLocations.length; ++i) {
371 // ImageData source = new ImageData(clazz.getResourceAsStream(
372 // imageLocations[i]));
373 // ImageData mask = source.getTransparencyMask();
374 // images[i] = new Image(null, source, mask);
375 // }
376 // }
377 return;
378 } catch (Throwable t) {
379 }
380 }
381 String error =
382 (resourceBundle != null) ? getResourceString("error.CouldNotLoadResources") : "Unable to load resources";
383 freeResources();
384 throw new RuntimeException(error);
385 }
386
387
388 void initProjectCollection() {
389 projectCollectionFile = new File(DEFAULT_PROJECTS_COLLECTION);
390 if ( projectCollectionFile.exists() ) {
391 // Load Collection
392 try {
393 XMLDecoder dec = new XMLDecoder(new FileInputStream(projectCollectionFile));
394 projects = (ProjectsCollection) dec.readObject();
395 dec.close();
396 } catch (FileNotFoundException e) {
397 // TODO! Auto-generated catch block
398 e.printStackTrace();
399 throw new RuntimeException(e);
400 }
401 } else {
402 // Create new collection
403 projects = new ProjectsCollection();
404 }
405 }
406
407 /***
408 * Frees the resources
409 */
410 void freeResources() {
411 // if (images != null) {
412 // for (int i = 0; i < images.length; ++i) {
413 // final Image image = images[i];
414 // if (image != null) image.dispose();
415 // }
416 // images = null;
417 // }
418 }
419
420 /***
421 * Disposes of all resources associated with a particular
422 * instance of the ControlExample.
423 */
424 public void dispose() {
425 /*
426 * Destroy any shells that may have been created
427 * by the Shells tab. When a shell is disposed,
428 * all child shells are also disposed. Therefore
429 * it is necessary to check for disposed shells
430 * in the shells list to avoid disposing a shell
431 * twice.
432 */
433 // if (shellTab != null) shellTab.closeAllShells ();
434 // shellTab = null;
435 tabFolder = null;
436 freeResources();
437 }
438
439 /***
440 * Invokes as a standalone program.
441 */
442 public static void main(String[] args) {
443 Display display = new Display();
444 Shell shell = new Shell(display);
445 shell.setLayout(new FillLayout());
446 XPCards instance = new XPCards(shell);
447 // shell.pack();
448 shell.open();
449 while (!shell.isDisposed()) {
450 if (!display.readAndDispatch())
451 display.sleep();
452 }
453 instance.dispose();
454 }
455
456 /***
457 * @return
458 */
459 public Enumeration projects() {
460 if (projects != null) {
461 return projects.projects();
462 }
463 return null;
464 }
465
466 public void putProject(ProjectSource element) throws Exception {
467 if (element == null) {
468 return;
469 }
470
471 projects.putProject(element);
472 }
473
474 private void updatePlanningTab(ModelElement element, ModelElement parent, String categoryName) {
475 updatePlanningTab(element, parent, categoryName, false);
476 }
477
478 public void invalidatePlanningTab() {
479 if (planningTab != null) {
480 planningTab.invalidateModel();
481 }
482 }
483
484 private void updatePlanningTab(ModelElement element, ModelElement parent, String categoryName, boolean recursive) {
485 if (planningTab != null) {
486 planningTab.putModelElementToCategory(element, parent, categoryName);
487 if (recursive) {
488 ModelElementCollection[] c = element.getChildrenCollections();
489 for (int i = 0; c != null && i < c.length; i++) {
490 for (Enumeration en = c[i].elements(); en != null && en.hasMoreElements();) {
491 updatePlanningTab((ModelElement) en.nextElement(), element, c[i].getCategory(), true);
492 }
493 }
494 }
495 }
496 }
497
498 /***
499 * @param element
500 */
501 public void removeProject(Project element) {
502 if (projects != null) {
503 projects.removeProject(element);
504 if (currentElement == element) {
505 selectModelElement(null);
506 }
507 }
508 }
509
510 public void selectModelElement(ModelElement p) {
511 //System.err.println("SelectModelElement:" + p);
512 if (currentElement != p) {
513 currentElement = p;
514 // Update selection
515 planningTab.selectModelElement(currentElement);
516 }
517 }
518
519 public ModelElement getSelectedModelElement() {
520 return currentElement;
521 }
522
523 // /***
524 // * @param prefix
525 // * @return
526 // */
527 // public String createProjectsUniqueIndex(String prefix) {
528 // if (projects == null) {
529 // setProjects(new ProjectsCollection());
530 // }
531 // return projects.createProjectsUniqueIndex(prefix);
532 // }
533
534 // /***
535 // * @return
536 // */
537 // public File getFile() {
538 // return file;
539 // }
540
541 /***
542 * @return
543 */
544 public boolean isModified() {
545 return isModified;
546 }
547
548 // /***
549 // * @param file
550 // */
551 // public void setFile(File file) {
552 // if (file == null) {
553 // // TODO I18n
554 // shell.setText("New collection");
555 // } else {
556 // shell.setText(file.getAbsolutePath());
557 // }
558 // this.file = file;
559 // }
560
561 /***
562 * @param b
563 */
564 public void setModified(boolean b) {
565 isModified = b;
566 }
567
568 public void serializeProjectsCollection(File file) throws FileNotFoundException {
569 XPEncoder enc = new XPEncoder(new FileOutputStream(file));
570
571 enc.writeObject(projects);
572 enc.close();
573 }
574
575 // public void deserializeProjectsCollection(File file) throws Exception {
576 // XMLDecoder dec = new XMLDecoder(new FileInputStream(file));
577 //
578 // ProjectsCollection c = (ProjectsCollection) dec.readObject();
579 // dec.close();
580 // if (c == null) {
581 // throw new Exception("Decoder error.");
582 // }
583 //
584 // setProjects(c);
585 // }
586
587 // private void setProjects(ProjectsCollection c) {
588 // // System.err.println("setProjects:" + c );
589 //
590 // if (projects != null) {
591 // projects.removeModelElementListener(modelListener);
592 // }
593 //
594 // // TODO Update project collection
595 //
596 //// invalidatePlanningTab();
597 // projects = c;
598 //// for (Enumeration en = projects.projects(); en != null && en.hasMoreElements();) {
599 //// updatePlanningTab((ModelElement) en.nextElement(), null, null, true);
600 //// }
601 //
602 // projectsTreeView.setInput(projects);
603 //
604 // projects.addModelElementListener(modelListener);
605 // setModified(false);
606 // }
607
608 public int[] getPiorities() {
609 return new int[] { 0, 1, 2, 3, 4, 5, 6, 7 };
610 }
611
612 public int[] getRisks() {
613 return new int[] { 0, 1, 2, 3, 4, 5, 6, 7 };
614 }
615
616 public ProjectsCollection getProjects() {
617 return projects;
618 }
619
620 }
This page was automatically generated by Maven