PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/genesis/org.dftproject.genesis.ui/src/org/dftproject/genesis/ui/pages/summary/SummaryPage.java

http://dftproject.googlecode.com/
Java | 547 lines | 458 code | 86 blank | 3 comment | 102 complexity | b2da184e712df3ca53ec48b3c699b693 MD5 | raw file
  1. package org.dftproject.genesis.ui.pages.summary;
  2. import java.util.Collections;
  3. import java.util.HashSet;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import java.util.Queue;
  7. import java.util.Set;
  8. import org.apache.commons.logging.Log;
  9. import org.apache.commons.logging.LogFactory;
  10. import org.dftproject.genesis.data.IAttribute;
  11. import org.dftproject.genesis.data.genealogy.Events;
  12. import org.dftproject.genesis.data.genealogy.GenealogyConstants;
  13. import org.dftproject.genesis.data.genealogy.GenealogyUtils;
  14. import org.dftproject.genesis.data.genealogy.IEvent;
  15. import org.dftproject.genesis.data.genealogy.IInstant;
  16. import org.dftproject.genesis.data.genealogy.IName;
  17. import org.dftproject.genesis.data.genealogy.INote;
  18. import org.dftproject.genesis.data.genealogy.IPerson;
  19. import org.dftproject.genesis.data.genealogy.IRole;
  20. import org.dftproject.genesis.data.genealogy.Sex;
  21. import org.dftproject.genesis.data.genealogy.impl.MergedPerson;
  22. import org.dftproject.genesis.ui.Activator;
  23. import org.dftproject.genesis.ui.figures.Caption;
  24. import org.dftproject.genesis.ui.figures.ColumnData;
  25. import org.dftproject.genesis.ui.figures.ColumnLayout;
  26. import org.dftproject.genesis.ui.figures.UniformSizeGroup;
  27. import org.dftproject.genesis.ui.pages.AbstractPagePart;
  28. import org.dftproject.genesis.ui.pages.IPageInput;
  29. import org.dftproject.genesis.ui.pages.IPageSite;
  30. import org.dftproject.genesis.ui.pages.PageInitException;
  31. import org.dftproject.genesis.ui.pages.PageManager;
  32. import org.dftproject.genesis.ui.pages.circlediagram.CircleDiagramIconFigure;
  33. import org.dftproject.genesis.ui.pages.circlediagram.CircleDiagramPage;
  34. import org.dftproject.genesis.ui.pages.circlediagram.CircleDiagramPageInput;
  35. import org.dftproject.genesis.ui.pages.pedigree.PedigreePage;
  36. import org.dftproject.genesis.ui.pages.pedigree.PedigreePageInput;
  37. import org.dftproject.genesis.ui.pages.pedigree.icon.PedigreeIconFigure;
  38. import org.dftproject.genesis.ui.pages.summary.details.DetailFigure;
  39. import org.dftproject.genesis.ui.pages.summary.details.DetailsPanel;
  40. import org.dftproject.genesis.ui.pages.summary.details.EventFigure;
  41. import org.dftproject.genesis.ui.pages.summary.details.FamilyFigure;
  42. import org.dftproject.genesis.ui.pages.summary.details.FigureListViewer;
  43. import org.dftproject.genesis.ui.pages.summary.details.IFigureProvider;
  44. import org.dftproject.genesis.ui.pages.summary.details.NameFigure;
  45. import org.dftproject.genesis.ui.pages.summary.details.NoteFigure;
  46. import org.dftproject.genesis.ui.pages.summary.details.SexFigure;
  47. import org.dftproject.genesis.ui.pages.summary.sources.FootnoteContainer;
  48. import org.dftproject.genesis.ui.widgets.gallery.Gallery;
  49. import org.eclipse.core.runtime.IProgressMonitor;
  50. import org.eclipse.core.runtime.IStatus;
  51. import org.eclipse.core.runtime.Status;
  52. import org.eclipse.core.runtime.jobs.Job;
  53. import org.eclipse.draw2d.ColorConstants;
  54. import org.eclipse.draw2d.Figure;
  55. import org.eclipse.draw2d.FigureCanvas;
  56. import org.eclipse.draw2d.IFigure;
  57. import org.eclipse.draw2d.MarginBorder;
  58. import org.eclipse.draw2d.Panel;
  59. import org.eclipse.draw2d.ToolbarLayout;
  60. import org.eclipse.jface.viewers.ISelection;
  61. import org.eclipse.jface.viewers.ISelectionChangedListener;
  62. import org.eclipse.jface.viewers.ISelectionProvider;
  63. import org.eclipse.jface.viewers.IStructuredContentProvider;
  64. import org.eclipse.jface.viewers.SelectionChangedEvent;
  65. import org.eclipse.jface.viewers.StructuredSelection;
  66. import org.eclipse.jface.viewers.Viewer;
  67. import org.eclipse.jface.viewers.ViewerComparator;
  68. import org.eclipse.swt.SWT;
  69. import org.eclipse.swt.layout.GridData;
  70. import org.eclipse.swt.layout.GridLayout;
  71. import org.eclipse.swt.widgets.Composite;
  72. import org.eclipse.swt.widgets.Display;
  73. import org.eclipse.ui.IWorkbench;
  74. import org.eclipse.ui.IWorkbenchPage;
  75. import org.eclipse.ui.IWorkbenchWindow;
  76. import org.eclipse.ui.PlatformUI;
  77. import com.eekbom.utils.Strings;
  78. public class SummaryPage extends AbstractPagePart {
  79. private static final Log log = LogFactory.getLog(SummaryPage.class);
  80. public static final String ID = SummaryPage.class.getName();
  81. private boolean updateScheduled;
  82. private final Queue<Object> updateQueue = new LinkedList<Object>();
  83. private final Runnable uiRunnable = new Runnable() {
  84. public void run() {
  85. updateScheduled = false;
  86. update();
  87. }
  88. };
  89. private FigureCanvas canvas;
  90. private FootnoteContainer footnoteContainer;
  91. private Caption caption;
  92. private FigureListViewer detailsViewer;
  93. private FigureListViewer familiesViewer;
  94. private final PersonSelectionProvider selectionProvider = new PersonSelectionProvider();
  95. private MergedPerson person;
  96. public void init(IPageSite site, IPageInput input) throws PageInitException {
  97. if (!(input instanceof SummaryPageInput))
  98. throw new PageInitException("input must be a " + SummaryPageInput.class.getName());
  99. this.setInput(input);
  100. site.setSelectionProvider(selectionProvider);
  101. selectionProvider.changed(((SummaryPageInput) input).getPerson());
  102. person = getMergedPerson(getSummaryPageInput().getPerson());
  103. }
  104. protected SummaryPageInput getSummaryPageInput() {
  105. return ((SummaryPageInput) this.getInput());
  106. }
  107. protected MergedPerson getMergedPerson(IPerson person) {
  108. if (person instanceof MergedPerson || person == null)
  109. return (MergedPerson) person;
  110. MergedPerson mergePerson = new MergedPerson(person);
  111. return mergePerson;
  112. }
  113. @Override
  114. public void createPartControl(Composite parent) {
  115. Composite container = new Composite(parent, SWT.NONE);
  116. GridLayout layout = new GridLayout();
  117. layout.marginWidth = layout.marginHeight = layout.marginTop = layout.marginRight = layout.marginBottom = layout.marginLeft = layout.horizontalSpacing = 0;
  118. layout.numColumns = 2;
  119. container.setLayout(layout);
  120. createGallery(container);
  121. Composite body = new Composite(container, SWT.NONE);
  122. layout = new GridLayout();
  123. layout.marginWidth = layout.marginHeight = layout.marginTop = layout.marginRight = layout.marginBottom = layout.marginLeft = layout.verticalSpacing = 0;
  124. body.setLayout(layout);
  125. body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  126. createContents(body);
  127. }
  128. protected void createGallery(Composite parent) {
  129. Gallery gallery = new Gallery(parent);
  130. gallery.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
  131. final IPerson person = ((SummaryPageInput) this.getInput()).getPerson();
  132. gallery.addItem(Activator.getImageDescriptor("icons/user.png").createImage(), true, "Summary", null);
  133. gallery.addItem(new PedigreeIconFigure(), false, "Pedigree", new Runnable() {
  134. public void run() {
  135. IWorkbench workbench = PlatformUI.getWorkbench();
  136. IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
  137. IWorkbenchPage workbenchPage = window.getActivePage();
  138. PageManager.getDefault().openPage(workbenchPage, new PedigreePageInput(person), PedigreePage.ID, true, false);
  139. }
  140. });
  141. gallery.addItem(new CircleDiagramIconFigure(), false, "Circle Diagram", new Runnable() {
  142. public void run() {
  143. IWorkbench workbench = PlatformUI.getWorkbench();
  144. IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
  145. IWorkbenchPage workbenchPage = window.getActivePage();
  146. PageManager.getDefault().openPage(workbenchPage, new CircleDiagramPageInput(person), CircleDiagramPage.ID, true, false);
  147. }
  148. });
  149. }
  150. protected void createContents(Composite parent) {
  151. // Create the main Draw2D canvas
  152. canvas = new FigureCanvas(parent);
  153. canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  154. // Create the root figure
  155. Panel container = new Panel();
  156. container.setBackgroundColor(ColorConstants.listBackground);
  157. ToolbarLayout layout = new ToolbarLayout(false);
  158. layout.setSpacing(20);
  159. container.setLayoutManager(layout);
  160. container.setBorder(new MarginBorder(10));
  161. canvas.setContents(container);
  162. canvas.getViewport().setContentsTracksWidth(true);
  163. caption = new Caption("(unknown)");
  164. container.add(caption);
  165. Figure columns = new Figure();
  166. columns.setLayoutManager(new ColumnLayout(10));
  167. container.add(columns);
  168. footnoteContainer = new FootnoteContainer(canvas.getViewport());
  169. container.add(footnoteContainer);
  170. createDetails(columns);
  171. createFamilies(columns);
  172. Job job = new Job("Populate page") {
  173. @Override
  174. protected IStatus run(IProgressMonitor monitor) {
  175. for (IAttribute attribute : person.getAttributes())
  176. scheduleUIUpdate(attribute);
  177. Set<IRole> roles = person.getRoles();
  178. for (IRole role : roles)
  179. scheduleUIUpdate(role);
  180. return Status.OK_STATUS;
  181. }
  182. };
  183. job.schedule();
  184. }
  185. protected void createDetails(IFigure parent) {
  186. IFigure detailsPanel = new DetailsPanel();
  187. parent.add(detailsPanel, new ColumnData(1));
  188. detailsViewer = new FigureListViewer(detailsPanel);
  189. detailsViewer.setContentProvider(new IStructuredContentProvider() {
  190. public Object[] getElements(Object inputElement) {
  191. return new Object[0];
  192. }
  193. public void dispose() {
  194. }
  195. public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  196. }
  197. });
  198. detailsViewer.setFigureProvider(new IFigureProvider() {
  199. private final UniformSizeGroup uniformSizeGroup = new UniformSizeGroup();
  200. public IFigure getFigure(Object element) {
  201. if (element instanceof IAttribute) {
  202. IAttribute attribute = (IAttribute) element;
  203. Object value = attribute.getValue();
  204. if (value instanceof IName) {
  205. return new DetailFigure(getLabel(attribute), new NameFigure((IName) value), uniformSizeGroup);
  206. } else if (value instanceof Sex) {
  207. SexFigure figure = new SexFigure((Sex) value, footnoteContainer);
  208. for (IAttribute sourceAttribute : attribute.getAttributes(GenealogyConstants.source))
  209. figure.addSource(sourceAttribute);
  210. return new DetailFigure(getLabel(attribute), figure, uniformSizeGroup);
  211. } else if (value instanceof INote) {
  212. NoteFigure figure = new NoteFigure(footnoteContainer);
  213. figure.setText(((INote) value).getContents());
  214. for (IAttribute sourceAttribute : attribute.getAttributes(GenealogyConstants.source))
  215. figure.addSource(sourceAttribute);
  216. return new DetailFigure(getLabel(attribute), figure, uniformSizeGroup);
  217. } else if (value instanceof String) {
  218. NoteFigure figure = new NoteFigure(footnoteContainer);
  219. figure.setText((String) value);
  220. for (IAttribute sourceAttribute : attribute.getAttributes(GenealogyConstants.source))
  221. figure.addSource(sourceAttribute);
  222. return new DetailFigure(getLabel(attribute), figure, uniformSizeGroup);
  223. }
  224. } else if (element instanceof IRole) {
  225. IRole role = (IRole) element;
  226. return new DetailFigure(getLabel(role), new EventFigure(role), uniformSizeGroup);
  227. }
  228. return null;
  229. }
  230. });
  231. detailsViewer.setComparator(new ViewerComparator() {
  232. @Override
  233. public int compare(Viewer viewer, Object o1, Object o2) {
  234. if (o2 instanceof IAttribute && o2 instanceof IAttribute) {
  235. IAttribute left = (IAttribute) o1;
  236. IAttribute right = (IAttribute) o2;
  237. if (!left.getName().equals(right.getName())) {
  238. if (GenealogyConstants.name.equals(left.getName()))
  239. return -1;
  240. if (GenealogyConstants.name.equals(right.getName()))
  241. return 1;
  242. if (GenealogyConstants.sex.equals(left.getName()))
  243. return -1;
  244. if (GenealogyConstants.sex.equals(right.getName()))
  245. return 1;
  246. int c = Strings.compareNatural(getLabel(left), getLabel(right));
  247. if (c != 0)
  248. return c;
  249. }
  250. return left.getValue().hashCode() - right.getValue().hashCode();
  251. } else if (o1 instanceof IRole && o2 instanceof IRole) {
  252. IRole left = (IRole) o1;
  253. IRole right = (IRole) o2;
  254. IInstant instant1 = (IInstant) GenealogyUtils.getValue(left.getEvent(), Events.instant, IInstant.class);
  255. IInstant instant2 = (IInstant) GenealogyUtils.getValue(right.getEvent(), Events.instant, IInstant.class);
  256. if (instant1 != null && instant2 != null) {
  257. Long millis1 = instant1.getMillis();
  258. Long millis2 = instant2.getMillis();
  259. if (millis1 != null && millis2 != null) {
  260. if (millis1 > millis2)
  261. return 1;
  262. if (millis1 < millis2)
  263. return -1;
  264. }
  265. }
  266. if (!left.getType().equals(right.getType())) {
  267. if (GenealogyConstants.Child.equals(left.getType()))
  268. return -1;
  269. if (GenealogyConstants.Child.equals(right.getType()))
  270. return 1;
  271. if (GenealogyConstants.Christened.equals(left.getType()))
  272. return -1;
  273. if (GenealogyConstants.Christened.equals(right.getType()))
  274. return 1;
  275. if (GenealogyConstants.Buried.equals(left.getType()))
  276. return 1;
  277. if (GenealogyConstants.Buried.equals(right.getType()))
  278. return -1;
  279. if (GenealogyConstants.Deceased.equals(left.getType()))
  280. return 1;
  281. if (GenealogyConstants.Deceased.equals(right.getType()))
  282. return -1;
  283. int c = Strings.compareNatural(getLabel(left), getLabel(right));
  284. if (c != 0)
  285. return c;
  286. }
  287. return left.getEvent().hashCode() - right.getEvent().hashCode();
  288. } else if (o1 instanceof IAttribute) {
  289. return -1;
  290. } else {
  291. return 1;
  292. }
  293. }
  294. });
  295. detailsViewer.setInput(getInput());
  296. }
  297. protected void createFamilies(IFigure parent) {
  298. IFigure familiesPanel = new DetailsPanel();
  299. parent.add(familiesPanel, new ColumnData());
  300. familiesViewer = new FigureListViewer(familiesPanel);
  301. familiesViewer.setContentProvider(new IStructuredContentProvider() {
  302. public Object[] getElements(Object inputElement) {
  303. return new Object[0];
  304. }
  305. public void dispose() {
  306. }
  307. public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  308. }
  309. });
  310. familiesViewer.setFigureProvider(new IFigureProvider() {
  311. public IFigure getFigure(Object element) {
  312. if (element instanceof IPerson) {
  313. IPerson spouse = (IPerson) element;
  314. return new FamilyFigure(spouse, person);
  315. }
  316. return null;
  317. }
  318. });
  319. familiesViewer.setComparator(new ViewerComparator() {
  320. @Override
  321. public int compare(Viewer viewer, Object o1, Object o2) {
  322. return o1.hashCode() - o2.hashCode();
  323. }
  324. });
  325. familiesViewer.setInput(getInput());
  326. }
  327. protected String getLabel(IAttribute attribute) {
  328. if (GenealogyConstants.name.equals(attribute.getName()))
  329. return "Name:";
  330. if (GenealogyConstants.sex.equals(attribute.getName()))
  331. return "Sex:";
  332. if (GenealogyConstants.note.equals(attribute.getName()))
  333. return "Note:";
  334. if (GenealogyConstants.afn.equals(attribute.getName()))
  335. return "Ancestral File Number:";
  336. if (GenealogyConstants.uid.equals(attribute.getName()))
  337. return "UID:";
  338. return "Unknown:";
  339. }
  340. protected String getLabel(IRole role) {
  341. if (GenealogyConstants.Child.equals(role.getType()))
  342. return "Birth:";
  343. if (GenealogyConstants.Christened.equals(role.getType()))
  344. return "Christening:";
  345. if (GenealogyConstants.Parent.equals(role.getType()))
  346. return "Child:";
  347. if (GenealogyConstants.Father.equals(role.getType()))
  348. return "Child:";
  349. if (GenealogyConstants.Mother.equals(role.getType()))
  350. return "Child:";
  351. if (GenealogyConstants.Spouse.equals(role.getType()))
  352. return "Marriage:";
  353. if (GenealogyConstants.Resided.equals(role.getType()))
  354. return "Residence:";
  355. if (GenealogyConstants.Immigrant.equals(role.getType()))
  356. return "Immigrated:";
  357. if (GenealogyConstants.Censused.equals(role.getType()))
  358. return "Census:";
  359. if (GenealogyConstants.Deceased.equals(role.getType()))
  360. return "Death:";
  361. if (GenealogyConstants.Buried.equals(role.getType()))
  362. return "Burial:";
  363. return "Unknown:";
  364. }
  365. @Override
  366. public void dispose() {
  367. }
  368. @Override
  369. public void setFocus() {
  370. canvas.setFocus();
  371. }
  372. protected void scheduleUIUpdate(Object item) {
  373. synchronized (updateQueue) {
  374. updateQueue.add(item);
  375. if (!updateScheduled) {
  376. updateScheduled = true;
  377. Display.getDefault().asyncExec(uiRunnable);
  378. }
  379. }
  380. }
  381. @SuppressWarnings("unchecked")
  382. protected void update() {
  383. synchronized (updateQueue) {
  384. Object item;
  385. while ((item = updateQueue.poll()) != null) {
  386. if (item instanceof IAttribute) {
  387. IAttribute attribute = (IAttribute) item;
  388. if (GenealogyConstants.name.equals(attribute.getName())) {
  389. IName name = (IName) attribute.getValue();
  390. if (name != null)
  391. caption.setText(GenealogyUtils.stringFromName(name));
  392. } else {
  393. detailsViewer.add(attribute);
  394. }
  395. } else if (item instanceof IRole) {
  396. IRole role = (IRole) item;
  397. if (GenealogyConstants.Spouse.equals(role.getType())) {
  398. IEvent event = role.getEvent();
  399. for (IRole spouseRole : event.getRoles(GenealogyConstants.Spouse)) {
  400. if (!person.sameAs(spouseRole.getPerson()))
  401. familiesViewer.add(spouseRole.getPerson());
  402. }
  403. } else if (GenealogyConstants.Parent.equals(role.getType()) || GenealogyConstants.Father.equals(role.getType()) || GenealogyConstants.Mother.equals(role.getType())) {
  404. IEvent event = role.getEvent();
  405. IPerson otherParent = null;
  406. for (IRole parentRole : event.getRoles(new String[] { GenealogyConstants.Parent, GenealogyConstants.Father, GenealogyConstants.Mother })) {
  407. if (!person.sameAs(parentRole.getPerson()))
  408. otherParent = parentRole.getPerson();
  409. }
  410. if (otherParent == null) {
  411. // TODO handle single parent case
  412. log.info("No other parent for event " + event);
  413. } else {
  414. for (IRole childRole : event.getRoles(GenealogyConstants.Child)) {
  415. int index = familiesViewer.getElementIndex(otherParent);
  416. if (index < 0) {
  417. familiesViewer.add(otherParent);
  418. index = familiesViewer.getElementIndex(otherParent);
  419. }
  420. IFigure figure = ((List<IFigure>) familiesViewer.getContainer().getChildren()).get(index);
  421. if (figure instanceof FamilyFigure)
  422. ((FamilyFigure) figure).addChild(childRole);
  423. }
  424. }
  425. } else {
  426. detailsViewer.add(role);
  427. }
  428. }
  429. }
  430. canvas.getContents().invalidate();
  431. }
  432. }
  433. protected class PersonSelectionProvider implements ISelectionProvider {
  434. private final Set<ISelectionChangedListener> listeners = Collections.synchronizedSet(new HashSet<ISelectionChangedListener>());
  435. private ISelection selection;
  436. public void addSelectionChangedListener(ISelectionChangedListener listener) {
  437. listeners.add(listener);
  438. }
  439. public ISelection getSelection() {
  440. return selection;
  441. }
  442. public void removeSelectionChangedListener(ISelectionChangedListener listener) {
  443. listeners.add(listener);
  444. }
  445. public void setSelection(ISelection selection) {
  446. if (this.selection == selection)
  447. return;
  448. this.selection = selection;
  449. synchronized (listeners) {
  450. if (!listeners.isEmpty()) {
  451. SelectionChangedEvent event = new SelectionChangedEvent(this, selection);
  452. for (ISelectionChangedListener listener : listeners)
  453. listener.selectionChanged(event);
  454. }
  455. }
  456. }
  457. public void changed(IPerson person) {
  458. setSelection(new StructuredSelection(person));
  459. }
  460. }
  461. }